最大获利
[NOI2006]不得不说远古的题还是比较水的。
这就是一个最大权闭合图的板子题,和拍照一模一样。
看代码:
#include<bits/stdc++.h> using namespace std; const int maxn=5*1e5+10; int beg[maxn],nex[maxn],to[maxn],w[maxn],e; inline void add(int x,int y,int z){ nex[e]=beg[x];beg[x]=e; to[e]=y;w[e]=z;e++; } int n,m,sum; inline int read(){ int x=0,f=1;char c=getchar(); while(c<'0'||c>'9'){if(c=='-')f=-1;c=getchar();} while(c>='0'&&c<='9'){x=(x<<1)+(x<<3)+c-'0';c=getchar();} return x*f; } int dep[maxn]; queue<int>q; inline int bfs(){ memset(dep,0x3f,sizeof(dep)); while(!q.empty())q.pop(); dep[0]=0;q.push(0); while(!q.empty()){ int x=q.front(); q.pop(); for(int i=beg[x];~i;i=nex[i]){ int t=to[i]; if(w[i]&&dep[t]>n+m+5){ dep[t]=dep[x]+1; q.push(t); } } } return dep[n+m+1]<n+m+5; } inline int dfs(int x,int lim){ if(x==n+m+1||!lim)return lim; int ans=0; for(int i=beg[x];~i;i=nex[i]){ int t=to[i]; if(w[i]&&dep[t]==dep[x]+1){ int f=dfs(t,min(lim,w[i])); lim-=f;ans+=f; w[i]-=f;w[i^1]+=f; } } return ans; } int main(){ memset(beg,-1,sizeof(beg)); n=read(),m=read(); int x,y,z; for(int i=1;i<=n;i++){ x=read(); add(0,i,x); add(i,0,0); } for(int i=n+1;i<=n+m;i++){ x=read(),y=read(),z=read(); sum+=z; add(x,i,1e9); add(i,x,0); add(y,i,1e9); add(i,y,0); add(i,n+m+1,z); add(n+m+1,i,0); } while(bfs())sum-=dfs(0,1e9); printf("%d\n",sum); return 0; }
深深地感到自己的弱小。