您的位置:首页 > 其它

[BZOJ1497][NOI2006]最大获利

2015-07-20 00:13 363 查看
原题地址

网络流经典模型——最大权闭合图.

AC code:

#include <cstdio>
#include <vector>
#include <queue>
#include <algorithm>
using namespace std;
const int N=100010;
const int INF=1<<28;
int n,m,s,t,ans;
int d
,cur
;

struct Edge{
int u,v,c,f;

Edge(int u,int v,int c,int f):u(u),v(v),c(c),f(f) {}
};
vector<Edge> E;
vector<int>  G
;

void addedge(int u,int v,int c){
E.push_back(Edge(u,v,c,0));
E.push_back(Edge(v,u,c,c));
G[u].push_back(E.size()-2);
G[v].push_back(E.size()-1);
}

void read(){
scanf("%d%d",&n,&m);
s=n+m+1;t=s+1;
for(int i=1;i<=n;i++){
int p;
scanf("%d",&p);
addedge(i,t,p);
}
for(int i=1;i<=m;i++){
int a,b,c;
scanf("%d%d%d",&a,&b,&c);
addedge(n+i,a,INF);
addedge(n+i,b,INF);
addedge(s,n+i,c);
ans+=c;
}
}

int BFS(){
for(int i=1;i<=t;i++) d[i]=cur[i]=0;
queue<int> Q;
Q.push(s);
while(!Q.empty()){
int x=Q.front();Q.pop();
for(int i=0;i<G[x].size();i++){
Edge e=E[G[x][i]];
if(e.v==s||d[e.v]||e.f==e.c) continue;
d[e.v]=d[x]+1;
Q.push(e.v);
}
}
return d[t];
}

int DFS(int x,int a){
if(x==t||(!a)) return a;
int tag=0,flow;
for(int &i=cur[x];i<G[x].size();i++){
Edge e=E[G[x][i]];
if(d[x]+1!=d[e.v]||e.f==e.c) continue;
flow=DFS(e.v,min(a-tag,e.c-e.f));
tag+=flow;
E[G[x][i]].f+=flow;
E[G[x][i]^1].f-=flow;
if(!(a-tag)) break;
}
return tag;
}

void Dinic(){
while(BFS()) ans-=DFS(s,INF);
}

int main(){
read();
Dinic();
printf("%d",ans);

return 0;
}

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: