博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
HDU 3251 Being a Hero 最小割
阅读量:4327 次
发布时间:2019-06-06

本文共 4915 字,大约阅读时间需要 16 分钟。

 

Problem Description
You are the hero who saved your country. As promised, the king will give you some cities of the country, and you can choose which ones to own!
But don't get too excited. The cities you take should NOT be reachable from the capital -- the king does not want to accidentally enter your area. In order to satisfy this condition, you have to destroy some roads. What's worse, you have to pay for that -- each road is associated with some positive cost. That is, your final income is the total value of the cities you take, minus the total cost of destroyed roads.
Note that each road is a unidirectional, i.e only one direction is available. Some cities are reserved for the king, so you cannot take any of them even if they're unreachable from the capital. The capital city is always the city number 1.
 

 

Input
The first line contains a single integer T (T <= 20), the number of test cases. Each case begins with three integers n, m, f (1 <= f < n <= 1000, 1 <= m < 100000), the number of cities, number of roads, and number of cities that you can take. Cities are numbered 1 to n. Each of the following m lines contains three integers u, v, w, denoting a road from city u to city v, with cost w. Each of the following f lines contains two integers u and w, denoting an available city u, with value w.
 

 

Output
For each test case, print the case number and the best final income in the first line. In the second line, print e, the number of roads you should destroy, followed by e integers, the IDs of the destroyed roads. Roads are numbered 1 to m in the same order they appear in the input. If there are more than one solution, any one will do.
 

 

Sample Input
2
4 4 2
1 2 2
1 3 3
3 2 4
2 4 1
2 3
4 4
4 4 2
1 2 2
1 3 3
3 2 1
2 4 1
2 3
4 4
 

 

Sample Output
Case 1:
3 1 4
Case 2:
4 2 1 3
题意:n个城市,m条有向带权边。可以选择f个城市,1是首都,要切断1和选择城市的路线,总价值是选择城市的价值减去摧毁的道路,求最大价值。
将带权的点连接到t上,容量就是该点的权值,s连接1,容量是INF。求最小割,利用总的点权和减去最小割就是获得的收益。
 
1 #include 
2 #include
3 #include
4 #include
5 #include
6 #define INF 0x3f3f3f3f 7 using namespace std; 8 const int M = 210010; 9 struct Nod { 10 int to, cap, next, index; 11 }edge[M]; 12 int T, n, m, f, s, t; 13 int head[M], level[M], vis[M], iter[M], sum, num; 14 void init() { 15 memset(head, -1, sizeof(head)); 16 memset(vis, 0, sizeof(vis)); 17 num = 0; 18 sum = 0; 19 } 20 void add_edge(int u, int v, int cap, int index) { 21 edge[num].to = v; edge[num].cap = cap; edge[num].next = head[u]; edge[num].index = index; head[u] = num++; 22 edge[num].to = u; edge[num].cap = 0; edge[num].next = head[v]; edge[num].index = -1; head[v] = num++; 23 } 24 bool bfs(int s, int t) { 25 memset(level, -1, sizeof(level)); 26 level[s] = 0; 27 queue
que; 28 que.push(s); 29 while(!que.empty()) { 30 int v = que.front(); 31 que.pop(); 32 for(int i = head[v]; i != -1; i = edge[i].next) { 33 int u = edge[i].to; 34 if(level[u] < 0 && edge[i].cap) { 35 level[u] = level[v] + 1; 36 que.push(u); 37 } 38 } 39 } 40 return level[t] != -1; 41 } 42 int dfs(int v, int t, int f) { 43 if(v == t) return f; 44 for(int &i = iter[v]; i != -1; i = edge[i].next) { 45 int u = edge[i].to; 46 if(level[u] > level[v] && edge[i].cap > 0) { 47 int d = dfs(u, t, min(f, edge[i].cap)); 48 if(d > 0) { 49 edge[i].cap -= d; 50 edge[i^1].cap += d; 51 return d; 52 } 53 } 54 } 55 level[v] = -1; 56 return 0; 57 } 58 int max_flow(int s, int t) { 59 int flow = 0; 60 while(bfs(s, t)) { 61 for(int i = 0; i <= t + 10; i ++) iter[i] = head[i]; 62 int f = 0; 63 while((f = dfs(s, t, INF)) > 0) flow += f; 64 } 65 return flow; 66 } 67 void dfs(int u, int fa) { 68 for(int i = head[u]; i != -1; i = edge[i].next) { 69 int v = edge[i].to; 70 if(!vis[v] && edge[i].cap) { 71 vis[v] = true; 72 dfs(v, u); 73 } 74 } 75 } 76 int main() { 77 ios::sync_with_stdio(false); 78 // cin >> T; 79 scanf("%d", &T); 80 int cas = 1; 81 while(T--) { 82 // cin >> n >> m >> f; 83 scanf("%d %d %d", &n, &m, &f); 84 init(); 85 add_edge(s, 1, INF, -1); 86 s = 0, t = n + 1; 87 for(int i = 1; i <= m; i ++) { 88 int u, v, w; 89 scanf("%d %d %d", &u, &v, &w); 90 add_edge(u, v, w, i); 91 } 92 for(int i = 1; i <= f; i ++) { 93 int u, w; 94 scanf("%d %d", &u, &w); 95 add_edge(u, t, w, -1); 96 sum += w; 97 } 98 int ans = max_flow(s, t); 99 ans = sum - ans;100 printf("Case %d: %d\n",cas++, ans);101 vis[1] = true;102 dfs(1, -1);103 queue
que;104 for(int i = 0; i < num; i += 2) { //0正1负105 if(vis[edge[i^1].to] && !vis[edge[i].to] && edge[i].index != -1) que.push(edge[i].index);106 }107 printf("%d",(int)que.size());108 while(!que.empty()) {109 printf(" %d",que.front());110 que.pop();111 }112 printf("\n");113 }114 return 0;115 }

 

转载于:https://www.cnblogs.com/xingkongyihao/p/7306127.html

你可能感兴趣的文章
IOS 杂笔-14(被人遗忘的owner)
查看>>
自动测试用工具
查看>>
前端基础之BOM和DOM
查看>>
[T-ARA/筷子兄弟][Little Apple]
查看>>
编译Libgdiplus遇到的问题
查看>>
【NOIP 模拟赛】Evensgn 剪树枝 树形dp
查看>>
java学习笔记④MySql数据库--01/02 database table 数据的增删改
查看>>
两台电脑如何实现共享文件
查看>>
组合模式Composite
查看>>
程序员最想得到的十大证件,你最想得到哪个?
查看>>
我的第一篇CBBLOGS博客
查看>>
【MyBean调试笔记】接口的使用和清理
查看>>
07 js自定义函数
查看>>
jQueru中数据交换格式XML和JSON对比
查看>>
form表单序列化后的数据转json对象
查看>>
[PYTHON]一个简单的单元測试框架
查看>>
iOS开发网络篇—XML数据的解析
查看>>
[BZOJ4303]数列
查看>>
一般处理程序在VS2012中打开问题
查看>>
C语言中的++和--
查看>>