网络流经典题
#include<iostream> #include<cstdio> #include<cmath> #include<cstring> #include<cstdlib> using namespace std; #define MAXN 610 #define MAXM 730000 #define INF 123456789 struct node_connect { int num; node_connect *next; }; struct node_dinic { int u,remain; node_dinic *next,*inv; }; node_dinic *graph[MAXN],epool[MAXM],*used[MAXN]; node_connect *graphs[MAXN],*grapht[MAXN],memo[MAXM]; int weight[MAXN]; int top=0,etop=0,label=0; int n,m,S=600,T=601,ans=0; int d[MAXN],finish[MAXN],mark[MAXN],cnt[MAXN],Q[MAXN]; bool use[MAXN]; void add1(int x,int y) { node_connect *p=&memo[top++]; p->num=y; p->next=graphs[x]; graphs[x]=p; p=&memo[top++]; p->num=x; p->next=grapht[y]; grapht[y]=p; } void add(int x,int y,int weight) { node_dinic *p=&epool[etop++],*q=&epool[etop++]; p->u=y; p->remain=weight; p->next=graph[x]; graph[x]=p; q->u=x; q->remain=0; q->next=graph[y]; graph[y]=q; p->inv=q; q->inv=p; } void dfs(int i) { use[i]=1; node_connect *p; for(p=graphs[i];p;p=p->next) if(!use[p->num]) dfs(p->num); finish[top++]=i; } void dfst(int i) { use[i]=1; cnt[label]++; mark[i]=label; node_connect *p; for(p=grapht[i];p;p=p->next) if(!use[p->num]) dfst(p->num); } void connect() { top=0; int i; memset(cnt,0,sizeof(cnt)); memset(use,0,sizeof(use)); for(i=0;i<n;i++) if(!use[i]) dfs(i); memset(use,0,sizeof(use)); for(i=n-1;i>=0;i--) if(!use[finish[i]]) { label++; dfst(finish[i]); } } void reduce() { top=0; memset(use,0,sizeof(use)); int i; node_connect *p; for(i=0;i<n;i++) if(!use[i]&&cnt[mark[i]]>1) dfs(i); for(i=0;i<n;i++) if(!use[i]) { if(weight[i]>0) add(S,i,weight[i]),ans+=weight[i]; else add(i,T,-weight[i]); for(p=graphs[i];p;p=p->next) add(p->num,i,INF); } } bool make_level() { memset(d,0xff,sizeof(d)); int head,tail; Q[head=tail=1]=T; d[T]=0; while(head<=tail) { int u=Q[head++]; used[u]=graph[u]; for(node_dinic *p=graph[u];p;p=p->next) { int v=p->u; if(p->inv->remain>0&&d[v]<0) { d[v]=d[u]+1; Q[++tail]=v; } } } return d[S]>=0; } int extend(int u,int delta) { int v,sum=0,temp; if(u==T) return delta; for(node_dinic *p=used[u];p;p=p->next) { used[u]=p;//重要优化 没优化之前第9个点T v=p->u; if(p->remain>0&&d[v]+1==d[u]) { temp=extend(v,min(delta,p->remain)); p->remain-=temp; p->inv->remain+=temp; sum+=temp;delta-=temp; if(delta==0) return sum; } } return sum; } void solve() { node_connect *p; int i; connect(); reduce(); int ret=0; while(make_level()) ret+=extend(S,INF); printf("%d\n",max(0,ans-ret)); } int main() { scanf("%d%d",&n,&m); int i,j,k,w,x,y,a,b; for(i=0;i<n;i++) for(j=0;j<m;j++) { scanf("%d",&x); a=i*m+j; weight[a]=x; scanf("%d",&w); for(k=1;k<=w;k++) { scanf("%d%d",&x,&y); b=x*m+y; add1(a,b); } if(j<m-1) add1(i*m+j+1,i*m+j); } n=n*m; solve(); return 0; }