HDUOJ--4888--Redraw Beautiful Drawings【isap】網路流+判環,網路流

來源:互聯網
上載者:User

HDUOJ--4888--Redraw Beautiful Drawings【isap】網路流+判環,網路流

連結:http://acm.hdu.edu.cn/showproblem.php?pid=4888

題意:一個矩陣,限定每行行和、列和,每個格子數字不超過k,問矩陣是否存在,如存在判斷有單解還是多解。


思路:之前多校的題目,那時候還不會網路流,現在A掉了,矩陣的建圖模型,判斷網路流是否可行只要判斷最大流是否等於總行和或總列和即可,判環是看的別人的解題報告,方法是使用dfs尋找殘餘網路中是否有還存在容量的弧形成了環,如果有,說明可以通過這個環改變容量網路內部的增廣路方式,而源匯的流量是不會變的,就說明存在多解。如果沒有環,就是單一解。

建圖:源點向每個行節點連弧,容量為該行行和,每個列節點向匯點連邊,容量為每個列和,每個行節點與每個列節點之間連邊,容量為k。

細節:我用的我之前AC過題目的isap模板,但是WA了,我debug之後發現錯誤不會在建圖和判環裡,然後就和別人的isap代碼對照,發現了一個不一樣的地方,改之AC,不懂為何,不一樣的地方代碼中有注釋。我的理解nn個點,源點src的層次是0,則最大的層次應該就是nn-1,但是minm初始化為nn-1是WA,初始化為nn就AC了。理論上應該是初始化大於等於nn-1都是可以的,以後還是就初始化為nn吧避免莫名其妙的WA。


#include<cstring>#include<string>#include<fstream>#include<iostream>#include<iomanip>#include<cstdio>#include<cctype>#include<algorithm>#include<queue>#include<map>#include<set>#include<vector>#include<stack>#include<ctime>#include<cstdlib>#include<functional>#include<cmath>using namespace std;#define PI acos(-1.0)#define MAXN 50100#define eps 1e-7#define INF 0x7FFFFFFF#define LLINF 0x7FFFFFFFFFFFFFFF#define seed 131#define MOD 1000000007#define ll long long#define ull unsigned ll#define lson l,m,rt<<1#define rson m+1,r,rt<<1|1struct node{    int u,v,w,next;}edge[500000];int head[820],dist[820],cur[820],fa[820],num[820],vis[820];int n,m,k,cnt,nn,src,sink;void add_edge(int a,int b,int c){    edge[cnt].u = a;    edge[cnt].v = b;    edge[cnt].w = c;    edge[cnt].next = head[a];    head[a] = cnt++;}void bfs(){    int x,i,j;    queue<int> q;    memset(dist,-1,sizeof(dist));    memset(num,0,sizeof(num));    q.push(sink);    dist[sink] = 0;    num[0] = 1;    while(!q.empty()){        x = q.front();        q.pop();        for(i=head[x];i!=-1;i=edge[i].next){            if(dist[edge[i].v]<0){                dist[edge[i].v] = dist[x] + 1;                num[dist[edge[i].v]]++;                q.push(edge[i].v);            }        }    }}int augment(){    int x=sink,a=INF;    while(x!=src){        a = min(a,edge[fa[x]].w);        x = edge[fa[x]].u;    }    x=sink;    while(x!=src){        edge[fa[x]].w -= a;        edge[fa[x]^1].w += a;        x = edge[fa[x]].u;    }    return a;}int isap(){    int i,x,ok,minm,flow=0;    bfs();    for(i=0;i<=nn+5;i++) cur[i] = head[i];    x=src;    while(dist[src]<nn){        if(x==sink){            flow += augment();            x = src;        }        ok=0;        for(i=cur[x];i!=-1;i=edge[i].next){            if(edge[i].w && dist[x]==dist[edge[i].v]+1){                ok=1;                fa[edge[i].v] = i;                cur[x] = i;                x = edge[i].v;                break;            }        }        if(!ok){            minm = nn;//minm = nn - 1 就WA            for(i=head[x];i!=-1;i=edge[i].next)                if(edge[i].w && dist[edge[i].v]<minm)   minm=dist[edge[i].v];            if(--num[dist[x]]==0)break;            num[dist[x]=minm+1]++;            cur[x]=head[x];            if(x!=src)  x=edge[fa[x]].u;        }    }    return flow;}bool dfs(int u,int pre){    int i,j;    if(vis[u])  return true;    vis[u] = 1;    for(i=head[u];i!=-1;i=edge[i].next){        if(edge[i].w>0&&edge[i].v!=pre&&dfs(edge[i].v,u))            return true;    }    vis[u] = 0;    return false;}int row[410],col[410];int ans[420][420];int main(){    int i,j;    int sumr,sumc;    while(scanf("%d%d%d",&n,&m,&k)!=EOF){        memset(head,-1,sizeof(head));        sumr = sumc = 0;        cnt = 0;        src = 0;        sink = n + m + 1;        nn = sink + 1;        for(i=1;i<=n;i++){            scanf("%d",&row[i]);            sumr += row[i];            add_edge(src,i,row[i]);            add_edge(i,src,0);            for(j=1;j<=m;j++){                add_edge(i,j+n,k);                add_edge(j+n,i,0);            }        }        for(i=1,j=n+1;i<=m;j++,i++){            scanf("%d",&col[i]);            sumc += col[i];            add_edge(j,sink,col[i]);            add_edge(sink,j,0);        }        if(sumr!=sumc){            puts("Impossible");            continue;        }        int flag = 0;        int flow = isap();        if(flow!=sumr){            puts("Impossible");            continue;        }        memset(vis,0,sizeof(vis));        for(i=1;i<=n;i++){            if(dfs(i,-1)){                flag = 1;                break;            }        }        if(flag){            puts("Not Unique");            continue;        }        puts("Unique");        memset(ans,0,sizeof(ans));        for(i=1;i<=n;i++){            for(j=head[i];j!=-1;j=edge[j].next){                int u = edge[j].v;                if(u>n&&u<=n+m){                    ans[i][u-n] = k - edge[j].w;                }            }        }        for(i=1;i<=n;i++){            for(j=1;j<=m;j++){                if(j>1) printf(" ");                printf("%d",ans[i][j]);            }            printf("\n");        }    }    return 0;}






聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.