最大权闭合图,建议和我一样不知道这个模型的acmer搜一下——国
#include <iostream> #include <cstdio> #include <queue> #include <cstring> using namespace std; const int maxn=2600; const int inf=200000000; const long long inf2=0x3f3f3f3f3f3f3f3fLL; struct Edge { int from,to,next; long long flow,cap; }; Edge e[maxn*60*2]; int head[maxn],map[110][30],cur[maxn],d[maxn],rel[maxn][55][2],gap[maxn],p[maxn]; long long cost[maxn]; int tot,num,s,t; long long totg; void addedge(int from,int to,long long cap) { e[tot].from=from;e[tot].to=to;e[tot].flow=0;e[tot].cap=cap; e[tot].next=head[from];head[from]=tot;tot++; e[tot].from=to;e[tot].to=from;e[tot].flow=0;e[tot].cap=0; e[tot].next=head[to];head[to]=tot;tot++; } long long augment() { int x=t; long long a=inf2; while(x!=s) { a=min(a,e[p[x]].cap-e[p[x]].flow); x=e[p[x]].from; } x=t; while(x!=s) { e[p[x]].flow+=a; e[p[x]^1].flow-=a; x=e[p[x]].from; } return a; } long long maxflow() { long long flow=0; memset(gap,0,sizeof(gap)); memset(d,0,sizeof(d)); gap[0]=t+1; int x=s; memcpy(cur,head,(t+1)*sizeof(int)); while(d[s]<=t+1-1) { if(x==t) { flow+=augment(); x=s; } int ok=0; for(int i=cur[x];i!=-1;i=e[i].next) { if(e[i].cap>e[i].flow&&d[x]==d[e[i].to]+1) { p[e[i].to]=i; ok=1; cur[x]=i; x=e[i].to; break; } } if(!ok) { int m=t+1-1; for(int i=head[x];i!=-1;i=e[i].next) { if(e[i].cap>e[i].flow) m=min(m,d[e[i].to]); } if(--gap[d[x]]==0) break; gap[d[x]=m+1]++; cur[x]=head[x]; if(x!=s) x=e[p[x]].from; } } return flow; } int main() { int amount,whe=0; cin>>amount; while(amount--) { whe++; memset(head,-1,sizeof(head)); memset(rel,-1,sizeof(rel)); tot=0;num=1;s=0;totg=0; int x,i,j,nlay,cos,val,fir,loc,ran,goldn,k; scanf("%d",&nlay); for(i=1;i<=nlay;i++) { scanf("%d",&goldn); for(j=1;j<=goldn;j++,num++) { map[i][j]=num; scanf("%d%d%d",&cos,&val,&fir); cost[num]=val-cos; if((val-cos)>0) totg+=(val-cos); for(k=0;k<fir;k++) { scanf("%d%d",&loc,&ran); rel[num][k][0]=loc;rel[num][k][1]=ran; } } } t=num; int tl,tr; for(i=1;i<=t-1;i++) { if(cost[i]>0) addedge(s,i,cost[i]); else addedge(i,t,-cost[i]); k=0; while(rel[i][k][0]!=-1) { addedge(i,map[rel[i][k][0]][rel[i][k][1]],inf2); k++; } } printf("Case #%d: %I64d\n",whe,totg-maxflow()); } return 0; }