网络流判圈

来源:互联网 发布:加内特季后赛数据 编辑:程序博客网 时间:2024/05/17 07:53

用残余网络进行判断。

#include<stdio.h>#include<iostream>#include<algorithm>#include<vector>#include<string.h>#include<queue>#define inf 100000000#define LL long long#define maxn 820using namespace std;struct pi{    int to;    int cost;    int rev;}pp;vector<pi >g[maxn];queue<int>q;int c[450][450];int s,t;int line[maxn],leve[maxn];bool vis[452][452];int min(int a,int b){    int p;    p=a;    if(b<a)        p=b;    return p;}void add(int a,int b,int cos){    pp.to=b;    pp.cost=cos;    pp.rev=(int)g[b].size();    g[a].push_back(pp);    pp.to=a;    pp.cost=0;    pp.rev=(int)g[a].size()-1;    g[b].push_back(pp);    return ;}void bfs(void){    q.push(s);    int p,f,i;    while(!q.empty())    {        p=q.front();        q.pop();        f=(int)g[p].size();        for(i=0;i<f;i++)        {            pi &e=g[p][i];            if(e.cost>0&&line[e.to]<0)            {                line[e.to]=line[p]+1;                q.push(e.to);            }        }    }    return ;}int dfs(int v,int f){    int p;    if(v==t)        return f;    for(int &i=leve[v];i<g[v].size();i++)    {        pi &e=g[v][i];        if(line[v]<line[e.to]&&e.cost>0)        {            p=dfs(e.to,min(f,e.cost));            if(p>0)            {                e.cost-=p;                g[e.to][e.rev].cost+=p;                return p;            }        }    }    return 0;}long long  dinic(){    int f;    long long flow=0;    while(1)    {        memset(line,-1,sizeof(line));        memset(leve,0,sizeof(leve));        line[s]=0;        bfs();        if(line[t]<0)            return flow;        f=dfs(s,inf);        if(f==0)            continue;        flow+=f;        while((f=dfs(s,inf))>0)        {            flow+=f;        }    }}int main(){    int i,j,n,m,p,k,f,f1,f2;    LL flow,s1,s2;    while(scanf("%d%d%d",&n,&m,&k)!=EOF){        for(i=0;i<=n+m+1;i++) g[i].clear();        s1=0;        s2=0;        f=0;        for(i=1;i<=n;i++){            scanf("%d",&p);            add(0,i,p);            if(p>k*m||p<0){                f=1;            }            s1+=p;        }        for(i=1;i<=m;i++){            scanf("%d",&p);            if(p>k*n||p<0){                f=1;            }            add(n+i,n+m+1,p);            s2+=p;        }        if(f){            printf("Impossible\n");            continue;        }        if(s1!=s2){            printf("Impossible\n");            continue;        }        for(i=1;i<=n;i++){            for(j=1;j<=m;j++){                add(i,n+j,k);            }        }        s=0;        t=n+m+1;        flow=dinic();        if(flow!=s1){            printf("Impossible\n");            continue;        }        for(i=1;i<=n;i++){            p=(int)g[i].size();            for(j=0;j<p;j++){                pp=g[i][j];                if(pp.to>n&&pp.to<=n+m)                    c[i][pp.to-n]=pp.cost;//用残量网络判断是否含环            }        }        memset(vis,0,sizeof(vis));//如果残量网络有两行全未达到极值说明图中流量不唯一,也就是说明图中含环        int flag=0;        for(i=1;i<=n;i++){            for(j=1;j<=m;j++){                for(p=j+1;p<=m;p++){                    f1=0,f2=0;                    if(c[i][j]!=0&&c[i][p]!=k){                        if(vis[p][j]){                            flag=1;                            break;                        }                        f1=1;                    }                    if(flag) break;                    if(c[i][j]!=k&&c[i][p]!=0){                        if(vis[j][p]){                            flag=1;                            break;                        }                        f2=1;                    }                    if(f1) vis[j][p]=1;                    if(f2) vis[p][j]=1;                }                if(flag) break;            }            if(flag) break;        }        if(flag){            printf("Not Unique\n");        }        else{            printf("Unique\n");            for(i=1;i<=n;i++){                for(j=1;j<=m;j++){                    if(j==1){                        printf("%d",k-c[i][j]);                    }                    else{                        printf(" %d",k-c[i][j]);                    }                }                printf("\n");            }        }    }}


0 0
原创粉丝点击