BZOJ 1497 最大权闭合图

题解:

边由被限制节点指向限制节点

 

View Code
 1 #include <iostream>
 2 #include <algorithm>
 3 #include <cstring>
 4 #include <cstdlib>
 5 #include <cstdio>
 6 
 7 #define N 120000
 8 #define M 2000100
 9 #define INF 1e9
10 
11 using namespace std;
12 
13 int head[N],next[M],to[M],len[M];
14 int layer[N],q[M];
15 int n,m,cnt,S,T,sum;
16 
17 inline void add(int u,int v,int w)
18 {
19     to[cnt]=v; len[cnt]=w; next[cnt]=head[u]; head[u]=cnt++;
20     to[cnt]=u; len[cnt]=0; next[cnt]=head[v]; head[v]=cnt++;
21 }
22 
23 inline void read()
24 {
25     memset(head,-1,sizeof head); cnt=0;
26     S=0; T=n+m+1; sum=0;
27     for(int i=1,a;i<=n;i++)
28     {
29         scanf("%d",&a);
30         add(i+m,T,a);
31     }
32     for(int i=1,a,b,c;i<=m;i++)
33     {
34         scanf("%d%d%d",&a,&b,&c);
35         add(S,i,c); add(i,a+m,INF); add(i,b+m,INF);
36         sum+=c;
37     }
38 }
39 
40 inline bool bfs()
41 {
42     memset(layer,-1,sizeof layer);
43     int h=1,t=2,sta;
44     q[1]=S; layer[S]=0;
45     while(h<t)
46     {
47         sta=q[h++];
48         for(int i=head[sta];~i;i=next[i])
49             if(len[i]&&layer[to[i]]<0)
50             {
51                 layer[to[i]]=layer[sta]+1;
52                 q[t++]=to[i];
53             }
54     }
55     return layer[T]!=-1;
56 }
57 
58 inline int find(int u,int cur_flow)
59 {
60     if(u==T) return cur_flow;
61     int res=0,tmp;
62     for(int i=head[u];~i&&res<cur_flow;i=next[i])
63         if(len[i]&&layer[to[i]]==layer[u]+1)
64         {
65             tmp=find(to[i],min(cur_flow-res,len[i]));
66             len[i]-=tmp; len[i^1]+=tmp; res+=tmp;
67         }
68     if(!res) layer[u]=-1;
69     return res;
70 }
71 
72 inline void go()
73 {
74     int ans=0;
75     while(bfs()) ans+=find(S,INF);
76     printf("%d\n",sum-ans);
77 }
78 
79 int main()
80 {
81     while(scanf("%d%d",&n,&m)!=EOF) read(),go();
82     return 0;
83 }

 

 

posted @ 2013-01-07 23:00  proverbs  阅读(345)  评论(0编辑  收藏  举报