hihoCoder 网络流五·最大权闭合子图 (网络流学习#5 记录)
链接:http://hihocoder.com/contest/hiho119/problem/1
#include<cstdio> #include<queue> using namespace std; const int N=205,M=205,INF=0x3f3f3f3f; const int maxn=N+M+10; int b,s=0,t,c[maxn][maxn],dis[maxn],ss; int n,m; #define Min(a,b) (a<b)?a:b int bfs() { for(int i=s+1; i<=t; i++) dis[i]=0; dis[s]=1; queue<int>q; q.push(s); while(!q.empty()) { int tmp=q.front(); q.pop(); for(int i=s+1; i<=t; i++) { if(c[tmp][i]>0&&!dis[i]) { dis[i]=dis[tmp]+1; q.push(i); } } } return dis[t]; } int dfs(int x,int v) { if(x==t||v==0) return v; int ans=0,tmp; for(int i=s+1; i<=t; i++) { if(dis[x]+1==dis[i]&&c[x][i]>0) { tmp=dfs(i,Min(v,c[x][i])); if(tmp<=0) continue; ans+=tmp; v-=tmp; c[x][i]-=tmp; c[i][x]+=tmp; if(v==0) break; } } return ans; } int work() { int ans=0; while(bfs()) { ans+=dfs(s,INF); } return max(ss-ans,0); } int main() { scanf("%d%d",&n,&m); t=n+m+1; ss=0; for(int i=s; i<=t; i++) for(int j=s; j<=t; j++) c[i][j]=0; for(int i=1; i<=m; i++) { scanf("%d",&b); c[n+i][t]+=b; } int a,k,x; for(int i=1; i<=n; i++) { scanf("%d%d",&a,&k); c[s][i]+=a; if(a>0) ss+=a; for(int j=0; j<k; j++) { scanf("%d",&x); c[i][n+x]=INF; } } printf("%d\n",work()); }
感觉现在普通最大流已经可以随便打了。wa了好几次因为N开小了,200看成100 。尴尬~