这个题是求最大权闭合图,具体可以看胡伯涛论文。悲剧的是以前的网络流模板果断超时,无奈找了一个新模板。
代码:
#include<cstdio> #include<cstring> #include<iostream> #include<queue> using namespace std; const int inf=1<<29; const int maxn=6e4; const int maxm=6e5; int e,st,des,pnt[maxm],nxt[maxm],flow[maxm],head[maxn],level[maxn]; int n,m,q[maxn]; void AddEdge(int u,int v,int f) { pnt[e]=v;nxt[e]=head[u];flow[e]=f;head[u]=e++; pnt[e]=u;nxt[e]=head[v];flow[e]=0;head[v]=e++; } bool BFS() { memset(level,0,sizeof(level)); level[st]=1; int pre=0,last=1; q[pre]=st; while(pre<last) { int u=q[pre++]; for(int i=head[u];i!=-1;i=nxt[i]) if(flow[i]&&!level[pnt[i]]) { level[pnt[i]]=level[u]+1; q[last++]=pnt[i]; } } return level[des]; } int DFS(int u,int maxf) { if(u==des||!maxf) return maxf; int f=0; for(int i=head[u];i!=-1;i=nxt[i]) if(flow[i]&&level[pnt[i]]==level[u]+1) { int t=DFS(pnt[i],min(flow[i],maxf-f)); if(t>0) { flow[i]-=t; flow[i^1]+=t; f+=t; if(f==maxf) break; } else level[pnt[i]]=0; } return f; } int maxflow() { int ans=0; while(BFS()) ans+=DFS(st,inf); return ans; } int main() { while(scanf("%d%d",&n,&m)!=EOF) { st=e=0;des=n+m+1; memset(head,-1,sizeof(head)); for(int i=1;i<=n;i++) { int val; scanf("%d",&val); AddEdge(m+i,des,val); } int profit=0; for(int i=1;i<=m;i++) { int u,v,c; scanf("%d%d%d",&u,&v,&c); profit+=c; AddEdge(i,m+u,inf); AddEdge(i,m+v,inf); AddEdge(st,i,c); } int f=maxflow(); printf("%d\n",profit-f); } return 0; }