http://acm.hdu.edu.cn/showproblem.php?pid=3996
题意 :
- 题意: 有 n 个金矿,每个金矿开发需要一定的价值,开发之后可以获得一定的价值,而且一些金矿受到另一些金矿的限制,即开采这个金矿之前要开采
- 限制它的金矿,问最多可以获得多少价值。
题解:
很明显的 最大权闭合图 金矿 ,有 开采的 花费 和价值 ,那么 开采的 利益就 是 价值 - 花费 ;
- 如果某个金矿的开发利润为正值,就在源点和该点之间连一条容量为该利润的边
- 如果某个金矿的开发利润为负值,就在该点和汇点之间连一条容量为该利润绝对值的边
- 如果某个金矿收到另一个金矿的限制,就在两个金矿之间连一条容量为INF的边。
- 累计所有正值利润的和 sum,获得的最大利润为sum - maxflow
1 #include<stdio.h>
2 #include<cstring>
3 #include<cmath>
4 #include<iostream>
5 #include<algorithm>
6 #include<set>
7 #include<map>
8 #include<queue>
9 #include<vector>
10 #include<string>
11 #define Min(a,b) a<b?a:b
12 #define Max(a,b) a>b?a:b
13 #define CL(a,num) memset(a,num,sizeof(a));
14 #define maxn 5100
15 #define eps 1e-6
16 #define inf 10000000000
17 #define read() freopen("data.in","r",stdin) ;
18 #define ll __int64
19 using namespace std;
20 ll n , m ;
21 struct node
22 {
23 int from;
24 int to ;
25 ll flow ;
26 int next ;
27 } p[maxn*100];
28 int head[maxn] ,s,t,cnt,dis[maxn];
29 ll a[maxn] ,ans,num,sum;
30
31 bool vis[maxn] ;
32
33 queue<int>que ;
34 void add(int from ,int to , ll flow )
35 {
36 p[cnt].to = to ;
37 p[cnt].flow =flow ;
38 p[cnt].next = head[from] ;
39 head[from] = cnt++ ;
40
41 p[cnt].to = from ;
42 p[cnt].flow = 0 ;
43 p[cnt].next = head[to] ;
44 head[to] = cnt++ ;
45
46 }
47
48 int bfs()
49 {
50 CL(dis,-1) ;
51 dis[s] = 0 ;
52 int i ;
53 while(!que.empty())que.pop() ;
54
55 que.push(s) ;
56 while(!que.empty())
57 {
58 int u = que.front() ;que.pop() ;
59
60 for(i = head[u] ; i != -1 ;i = p[i].next)
61 {
62 int v = p[i].to ;
63
64 ll flow = p[i].flow ;
65
66 if(flow > 0)
67 if(dis[v] < 0 )
68 {
69 dis[v] = dis[u] + 1 ;
70 que.push(v) ;
71 }
72
73 }
74
75 }
76
77 if(dis[t] > 0) return 1;
78 else return 0 ;
79
80
81
82 }
83
84
85 ll dfs(int x,ll mx)
86 {
87
88
89 if(x == t) return mx ;
90
91 int i ;
92 ll a ,tf = 0;
93
94
95 for(i = head[x] ; i != -1 ; i = p[i].next)
96 {
97 int v = p[i].to ;
98 ll flow = p[i].flow ;
99 if(flow > 0)
100 {
101 if( dis[v] == dis[x] + 1 && (a = dfs(v,min(flow ,mx))))
102 {
103 p[i].flow -= a ;
104 p[i^1].flow += a;
105
106 return a ;
107 }
108
109 }
110
111 }
112
113
114 if(!tf) dis[x] = - 1;
115 return tf ;
116
117 }
118
119 ll dinic()
120 {
121
122 ans = 0 ;
123 ll res = 0 ;
124 while(bfs())
125 {
126 while(res = dfs(s,inf))ans += res ;
127 }
128
129 return ans ;
130
131
132 }
133
134 int main()
135 {
136 int T,i,j,a,b,num ;
137 ll cost ,val;
138 scanf("%d",&T);
139 int cas = 0 ;
140 ll sum ;
141 while(T--)
142 {
143
144 CL(head, -1) ;
145 cnt = 0 ;
146 sum = 0 ;
147 scanf("%d",&n);
148
149 s = 0 ;
150 t = n*26 + n + 1 ;
151
152 for(i = 1 ; i <= n;i++)
153 {
154 scanf("%d",&m);
155 for(j = 1 ; j <= m;j++)
156 {
157 scanf("%I64d%I64d%d",&cost,&val,&num);
158
159 ll tmp = val - cost ;
160 if(tmp > 0)
161 {
162 add(s,i*26 + j,tmp);
163
164 sum += tmp ;
165 }
166 else
167 {
168 add(i*26 + j,t, -tmp) ;
169
170 }
171
172
173 while(num--)
174 {
175 scanf("%d%d",&a,&b);
176 add(i*26+j,a*26 + b,inf) ;
177 }
178 }
179 }
180
181 ll ans = dinic() ;
182
183 printf("Case #%d: %I64d\n",++cas,sum - ans) ;
184
185 }
186 }
2 #include<cstring>
3 #include<cmath>
4 #include<iostream>
5 #include<algorithm>
6 #include<set>
7 #include<map>
8 #include<queue>
9 #include<vector>
10 #include<string>
11 #define Min(a,b) a<b?a:b
12 #define Max(a,b) a>b?a:b
13 #define CL(a,num) memset(a,num,sizeof(a));
14 #define maxn 5100
15 #define eps 1e-6
16 #define inf 10000000000
17 #define read() freopen("data.in","r",stdin) ;
18 #define ll __int64
19 using namespace std;
20 ll n , m ;
21 struct node
22 {
23 int from;
24 int to ;
25 ll flow ;
26 int next ;
27 } p[maxn*100];
28 int head[maxn] ,s,t,cnt,dis[maxn];
29 ll a[maxn] ,ans,num,sum;
30
31 bool vis[maxn] ;
32
33 queue<int>que ;
34 void add(int from ,int to , ll flow )
35 {
36 p[cnt].to = to ;
37 p[cnt].flow =flow ;
38 p[cnt].next = head[from] ;
39 head[from] = cnt++ ;
40
41 p[cnt].to = from ;
42 p[cnt].flow = 0 ;
43 p[cnt].next = head[to] ;
44 head[to] = cnt++ ;
45
46 }
47
48 int bfs()
49 {
50 CL(dis,-1) ;
51 dis[s] = 0 ;
52 int i ;
53 while(!que.empty())que.pop() ;
54
55 que.push(s) ;
56 while(!que.empty())
57 {
58 int u = que.front() ;que.pop() ;
59
60 for(i = head[u] ; i != -1 ;i = p[i].next)
61 {
62 int v = p[i].to ;
63
64 ll flow = p[i].flow ;
65
66 if(flow > 0)
67 if(dis[v] < 0 )
68 {
69 dis[v] = dis[u] + 1 ;
70 que.push(v) ;
71 }
72
73 }
74
75 }
76
77 if(dis[t] > 0) return 1;
78 else return 0 ;
79
80
81
82 }
83
84
85 ll dfs(int x,ll mx)
86 {
87
88
89 if(x == t) return mx ;
90
91 int i ;
92 ll a ,tf = 0;
93
94
95 for(i = head[x] ; i != -1 ; i = p[i].next)
96 {
97 int v = p[i].to ;
98 ll flow = p[i].flow ;
99 if(flow > 0)
100 {
101 if( dis[v] == dis[x] + 1 && (a = dfs(v,min(flow ,mx))))
102 {
103 p[i].flow -= a ;
104 p[i^1].flow += a;
105
106 return a ;
107 }
108
109 }
110
111 }
112
113
114 if(!tf) dis[x] = - 1;
115 return tf ;
116
117 }
118
119 ll dinic()
120 {
121
122 ans = 0 ;
123 ll res = 0 ;
124 while(bfs())
125 {
126 while(res = dfs(s,inf))ans += res ;
127 }
128
129 return ans ;
130
131
132 }
133
134 int main()
135 {
136 int T,i,j,a,b,num ;
137 ll cost ,val;
138 scanf("%d",&T);
139 int cas = 0 ;
140 ll sum ;
141 while(T--)
142 {
143
144 CL(head, -1) ;
145 cnt = 0 ;
146 sum = 0 ;
147 scanf("%d",&n);
148
149 s = 0 ;
150 t = n*26 + n + 1 ;
151
152 for(i = 1 ; i <= n;i++)
153 {
154 scanf("%d",&m);
155 for(j = 1 ; j <= m;j++)
156 {
157 scanf("%I64d%I64d%d",&cost,&val,&num);
158
159 ll tmp = val - cost ;
160 if(tmp > 0)
161 {
162 add(s,i*26 + j,tmp);
163
164 sum += tmp ;
165 }
166 else
167 {
168 add(i*26 + j,t, -tmp) ;
169
170 }
171
172
173 while(num--)
174 {
175 scanf("%d%d",&a,&b);
176 add(i*26+j,a*26 + b,inf) ;
177 }
178 }
179 }
180
181 ll ans = dinic() ;
182
183 printf("Case #%d: %I64d\n",++cas,sum - ans) ;
184
185 }
186 }