poj1149 PIGS 神奇的建图 最大流

来源:互联网 发布:cbox网络电视官方网站 编辑:程序博客网 时间:2024/05/05 17:32

建图详细解释请看转发的博文

代码:

#include<iostream> #include<cstdio>#include<cstring> #include<cmath> using namespace std;   #define MAXN 200 #define MAXE 5000 #define INF 0xfffff   int ne,nv,tmp,s,t,index;  struct Edge{     int next,pair,v;     int cap,fLow; }edge[MAXE];int g[1010][110];int net[MAXN]; int ISAP() {     int numb[MAXN],dist[MAXN],curedge[MAXN],pre[MAXN];     int cur_fLow,max_fLow;int u,tmp,neck,i;     memset(dist,0,sizeof(dist));     memset(numb,0,sizeof(numb));     memset(pre,-1,sizeof(pre));     for(i = 1 ; i <= nv ; ++i)         curedge[i] = net[i];     numb[nv] = nv;     max_fLow = 0;     u = s;     while(dist[s] < nv)     {         if(u == t)         {             cur_fLow = INF+1;             for(i = s; i != t;i = edge[curedge[i]].v)              {                   if(cur_fLow > edge[curedge[i]].cap)                 {                     neck = i;                     cur_fLow = edge[curedge[i]].cap;                 }             }             for(i = s; i != t; i = edge[curedge[i]].v)             {                 tmp = curedge[i];                 edge[tmp].cap -= cur_fLow;                 edge[tmp].fLow += cur_fLow;                 tmp = edge[tmp].pair;                 edge[tmp].cap += cur_fLow;                 edge[tmp].fLow -= cur_fLow;             }             max_fLow += cur_fLow;             u = neck;         }        for(i = curedge[u]; i != -1; i = edge[i].next)             if(edge[i].cap > 0 && dist[u] == dist[edge[i].v]+1)                 break;         if(i != -1)         {             curedge[u] = i;             pre[edge[i].v] = u;             u = edge[i].v;         }else{             if(0 == --numb[dist[u]]) break;             curedge[u] = net[u];             for(tmp = nv,i = net[u]; i != -1; i = edge[i].next)                 if(edge[i].cap > 0)                     tmp = tmp<dist[edge[i].v]?tmp:dist[edge[i].v];             dist[u] = tmp + 1;             ++numb[dist[u]];             if(u != s) u = pre[u];         }     }          return max_fLow; }void addedge(int u,int v,int f){    edge[index].next = net[u];     edge[index].v = v;     edge[index].cap = f;     edge[index].fLow = 0;     edge[index].pair = index+1;     net[u] = index++;     edge[index].next = net[v];     edge[index].v = u;     edge[index].cap = 0;     edge[index].fLow = 0;     edge[index].pair = index-1;     net[v] = index++;    } int main() {     int i,j,m,n;         int sum;    int pig[1010];    int vis[1010];    while(~scanf("%d%d",&m,&n))     { memset(pig,0,sizeof(pig));sum=0;index=0;        s = 0;         t = n+1;nv=t+1;memset(g,0,sizeof(g));        memset(net,-1,sizeof(net));memset(vis,0,sizeof(vis));                for(i=1;i<=m;i++)        {scanf("%d",&pig[i]);}for(i=1;i<=n;i++){int k;scanf("%d",&k);for(j=1;j<=k;j++){int temp;scanf("%d",&temp);g[temp][i]=1;if(vis[temp]==0){addedge(s,i,pig[temp]);vis[temp]=1;}}int temp;scanf("%d",&temp);addedge(i,t,temp);}for(i=1;i<=m;i++){int first=1;int prepig;for(j=1;j<=n;j++){if(first){if(g[i][j]){first=0;prepig=j;}}else{if(g[i][j]){addedge(prepig,j,INF);prepig=j;}}}}        int ans=ISAP();        printf("%d\n",ans);    }     return 0; }