码迷,mamicode.com
首页 > 其他好文 > 详细

BZOJ 1497 最大获利(最大权闭合子图)

时间:2016-06-12 20:12:55      阅读:158      评论:0      收藏:0      [点我收藏+]

标签:

http://www.lydsy.com/JudgeOnline/problem.php?id=1497

思路:由题意可以得知,每个顾客都依赖2个中转站,那么让中转站连有向边到汇点,流量为它的建设费用,源点连到每个顾客,流量为赚的钱,然后每个顾客到它依赖的中转站连流量为inf的边

 1 #include<algorithm>
 2 #include<cstdio>
 3 #include<cmath>
 4 #include<cstring>
 5 #include<iostream>
 6 #define inf 0x7fffffff
 7 int tot,go[500005],first[500005],next[500005],flow[500005];
 8 int op[500005],S,T,nodes,dis[500005],cnt[500005],n,m;
 9 int read(){
10     int t=0,f=1;char ch=getchar();
11     while (ch<0||ch>9){if (ch==-) f=-1;ch=getchar();}
12     while (0<=ch&&ch<=9){t=t*10+ch-0;ch=getchar();}
13     return t*f;
14 }
15 void insert(int x,int y,int z){
16     tot++;
17     go[tot]=y;
18     next[tot]=first[x];
19     first[x]=tot;
20     flow[tot]=z;
21 }
22 void add(int x,int y,int z){
23     insert(x,y,z);op[tot]=tot+1;
24     insert(y,x,0);op[tot]=tot-1;
25 }
26 int dfs(int x,int f){
27     if (x==T) return f;
28     int mn=nodes,sum=0;
29     for (int i=first[x];i;i=next[i]){
30         int pur=go[i];
31         if (flow[i]&&dis[pur]+1==dis[x]){
32             int save=dfs(pur,std::min(f-sum,flow[i]));
33             sum+=save;
34             flow[i]-=save;
35             flow[op[i]]+=save;
36             if (f==sum||dis[S]>=nodes) return sum;
37         }
38         if (flow[i]) mn=std::min(mn,dis[pur]); 
39     }
40     if (sum==0){
41         cnt[dis[x]]--;
42         if (cnt[dis[x]]==0){
43             dis[S]=nodes;
44         }
45         else{
46             dis[x]=mn+1;
47             cnt[dis[x]]++;
48         }
49     }
50     return sum;
51 }
52 int main(){
53     n=read(),m=read();
54     nodes=n+m+2;
55     T=n+m+1;S=0;
56     for (int i=1;i<=n;i++){
57      int x=read();
58      add(m+i,T,x);
59     }
60     int sum=0;
61     for (int i=1;i<=m;i++){
62         int x=read(),y=read(),z=read();
63         add(S,i,z);
64         add(i,x+m,inf);
65         add(i,y+m,inf);
66         sum+=z;
67     }
68     int ans=0;
69     while (dis[S]<nodes) ans+=dfs(S,inf);
70     printf("%d\n",std::max(sum-ans,0));
71 }

 

BZOJ 1497 最大获利(最大权闭合子图)

标签:

原文地址:http://www.cnblogs.com/qzqzgfy/p/5578568.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!