网络流24题之T7 试题库问题

来源:互联网 发布:联排牙的利与弊 知乎 编辑:程序博客网 时间:2024/05/09 02:02
#include <cstdio>#include <iostream>#include <cstdlib>#include <algorithm>#include <cstring>#include <queue>using namespace std ;const int maxn=1010;const int oo=1000000000;typedef struct EDGE{    int u,v;    int c,f,next;    EDGE (){        u=v=c=f=0;        next=-1;    }    EDGE (int a,int b,int d,int e,int g){        u=a;v=b;c=d;f=e;next=g;    }}E;E edge[100*maxn+10];int len=-1,head[maxn],n,m;int vis[maxn],dis[maxn];int cur[maxn],sum=0;int times=1;//避免每次都memset,减少时间复杂度int allp;//总的点个数int S,T;//源点和汇点的编号void E_add (int s,int t,int x,int y){    edge[++len]=EDGE (s,t,x,y,head[s]);    head[s]=len;}void init (){    freopen ("prog87.in","r",stdin);    freopen ("prog87.out","w",stdout);    cin >>n >>m;    int i,j,k,l;    S=m+n+1;    T=m+n+2;    allp=T;    memset (head,-1,sizeof (head));    //读入并加边    for (i=1;i<=n;i++){        scanf ("%d",&j);        E_add (S,i,j,0);        E_add (i,S,0,0);        sum+=j;    }    for (i=1;i<=m;i++){        scanf ("%d",&j);        E_add (i+n,T,1,0);        E_add (T,i+n,0,0);        for (k=1;k<=j;k++){            scanf ("%d",&l);            E_add (l,i+n,1,0);            E_add (i+n,l,0,0);        }    }}int bfs (){    int q[100*maxn],headx=0,tail=0;    int now,i;    q[tail++]=S;    vis[S]=++times;    dis[S]=1;    while (headx<tail){        now=q[headx++];        for (i=head[now];i!=-1;i=edge[i].next){            if (vis[edge[i].v]!=times&&edge[i].c>edge[i].f) {                q[tail++]=edge[i].v;                dis[edge[i].v]=dis[now]+1;                vis[edge[i].v]=times;            }        }    }    return vis[T]==times;}int dfs (int x,int fmax){    if (x==T||fmax==0) return fmax;    int f,flow=0,&now=cur[x];    for (;now!=-1;now=edge[now].next){        if (dis[edge[now].v]==dis[x]+1&&(f=(dfs (edge[now].v,min(fmax,edge[now].c-edge[now].f))))){            flow+=f;            edge[now].f+=f;            edge[now^1].f-=f;            fmax-=f;            if (fmax==0) break;        }    }    return flow;}int dinic (){    int flow=0,i;    while (bfs ()){        for (i=1;i<=allp;i++) cur[i]=head[i];        flow+=dfs (S,oo);    }    return flow;}int main (){    init ();    if (sum==dinic ()) cout <<1;    else cout <<"No Solution!";    return 0;}
0 0