POJ 2987 Firing 网络流 最大权闭合图

http://poj.org/problem?id=2987

https://blog.csdn.net/u014686462/article/details/48533253

给一个闭合图,要求输出其最大权闭合图的权值和需要选的最少点数,最大权闭合图定义和网络流连边方式见博客。

 1 #include<cstdio>
 2 #include<cstring>
 3 #include<algorithm>
 4 #include<cmath>
 5 #include<iostream>
 6 #include<queue>
 7 using namespace std;
 8 #define LL long long
 9 const int maxn=10010;
10 const LL minf=(LL)1e14;
11 int n,m,s,t;
12 LL val[maxn]={};
13 struct nod{
14     int y,next;LL v;
15 }e[maxn*20];
16 int head[maxn],tot=1;
17 queue<int>q;
18 int dep[maxn]={},vis[maxn]={},id[maxn]={},tai=0;
19 void init(int x,int y,LL v){
20     e[++tot].y=y;e[tot].v=v;e[tot].next=head[x];head[x]=tot;
21 }
22 bool dfs(){
23     memset(dep,0,sizeof(dep));
24     q.push(s);dep[s]=1;
25     while(!q.empty()){
26         int x=q.front();q.pop();
27         for(int i=head[x];i;i=e[i].next){
28             if(e[i].v&&!dep[e[i].y]){
29                 dep[e[i].y]=dep[x]+1;
30                 q.push(e[i].y);
31             }
32         }
33     }
34     return dep[t];
35 }
36 LL dfs1(int x,LL fc){
37     if(x==t){
38         return fc;
39     }
40     LL he=0,z;
41     for(int i=head[x];i;i=e[i].next){
42         if(dep[x]+1==dep[e[i].y]){
43             z=dfs1(e[i].y,min(fc-he,e[i].v));
44             he+=z;e[i].v-=z;e[i^1].v+=z;
45             if(he==fc)break;
46         }
47     }
48     return he;
49 }
50 void dfs2(int x){
51     if(x==t)return;
52     if(x!=s)id[++tai]=x;
53     vis[x]=1;
54     for(int i=head[x];i;i=e[i].next){
55         if(e[i].v&&!vis[e[i].y]){
56             dfs2(e[i].y);
57         }
58     }
59 }
60 int main(){
61     int x,y; LL ans=0;
62     scanf("%d%d",&n,&m);
63     s=n+1;t=s+1;
64     for(int i=1;i<=n;i++){
65         scanf("%lld",&val[i]);
66         if(val[i]>=0){init(s,i,val[i]);init(i,s,0);ans=ans+val[i];}
67         else {init(i,t,-val[i]);init(t,i,0);}
68     }
69     for(int i=1;i<=m;i++){
70         scanf("%d%d",&x,&y);
71         init(x,y,minf);init(y,x,0);
72     }
73     while(dfs())ans-=dfs1(s,minf);
74     dfs2(s);
75     printf("%d ",tai);
76     printf("%lld\n",ans);
77     return 0;
78 }
View Code

 

posted @ 2018-05-28 16:29  鲸头鹳  阅读(169)  评论(0编辑  收藏  举报