Harry Potter and the Forbidden Forest HDU - 3987
Harry Potter notices some Death Eaters try to slip into Castle. The Death Eaters hide in the most depths of Forbidden Forest. Harry need stop them as soon as.
The Forbidden Forest is mysterious. It consists of N nodes numbered from 0 to N-1. All of Death Eaters stay in the node numbered 0. The position of Castle is node n-1. The nodes connected by some roads. Harry need block some roads by magic and he want to minimize the cost. But it’s not enough, Harry want to know how many roads are blocked at least.
The Forbidden Forest is mysterious. It consists of N nodes numbered from 0 to N-1. All of Death Eaters stay in the node numbered 0. The position of Castle is node n-1. The nodes connected by some roads. Harry need block some roads by magic and he want to minimize the cost. But it’s not enough, Harry want to know how many roads are blocked at least.
InputInput consists of several test cases.
The first line is number of test case.
Each test case, the first line contains two integers n, m, which means the number of nodes and edges of the graph. Each node is numbered 0 to n-1.
Following m lines contains information about edges. Each line has four integers u, v, c, d. The first two integers mean two endpoints of the edges. The third one is cost of block the edge. The fourth one means directed (d = 0) or undirected (d = 1).
Technical Specification
1. 2 <= n <= 1000
2. 0 <= m <= 100000
3. 0 <= u, v <= n-1
4. 0 < c <= 1000000
5. 0 <= d <= 1
OutputFor each test case:
Output the case number and the answer of how many roads are blocked at least.
Sample Input
3 4 5 0 1 3 0 0 2 1 0 1 2 1 1 1 3 1 1 2 3 3 1 6 7 0 1 1 0 0 2 1 0 0 3 1 0 1 4 1 0 2 4 1 0 3 5 1 0 4 5 2 0 3 6 0 1 1 0 0 1 2 0 1 1 1 1 1 2 1 0 1 2 1 0 2 1 1 1
Sample Output
Case 1: 3 Case 2: 2 Case 3: 2
题解:跑一遍最大流,根据正向边的容量是否为0,来判断哪些边包含在最小割里面。然后令最小割里面的边的容量为1,反向边的容量为0,而其它不属于最小割的边的容量为INF。再跑一遍最大流。
1 // ConsoleApplication3.cpp: 定义控制台应用程序的入口点。 2 // 3 4 #include "stdafx.h" 5 #include<queue> 6 #include<cstdio> 7 #include<cstring> 8 #include<iostream> 9 #include<algorithm> 10 using namespace std; 11 12 const int maxn = 1005; 13 const int maxm = 400005; //注意是4倍,因为有双向边存在,否则会TLE!!!! 14 const int INF = 0x3f3f3f3f; 15 16 struct node { 17 int to, cap, next; 18 }e[maxm]; 19 20 int n, m, kase, tot, src, des; 21 int head[maxn],dep[maxn]; 22 23 void Inite() { 24 des = n - 1; 25 src = tot = 0; 26 memset(head, -1, sizeof(head)); 27 } 28 29 void addedge(int u, int v, int w) { 30 e[tot].to = v, e[tot].cap = w, e[tot].next = head[u], head[u] = tot++; 31 e[tot].to = u, e[tot].cap = 0, e[tot].next = head[v], head[v] = tot++; 32 } 33 34 int BFS() { 35 memset(dep, -1, sizeof(dep)); 36 dep[src] = 0; 37 queue<int> q; 38 q.push(src); 39 while (!q.empty()) { 40 int u = q.front(); 41 q.pop(); 42 for (int i = head[u]; i != -1; i = e[i].next) { 43 int v = e[i].to; 44 if (e[i].cap > 0 && dep[v] == -1) { 45 dep[v] = dep[u] + 1; 46 q.push(v); 47 } 48 } 49 } 50 return dep[des] != -1; 51 } 52 53 int DFS(int u, int minx) { 54 if (u == des) return minx; 55 int temp; 56 for (int i = head[u]; i != -1; i = e[i].next) { 57 int v = e[i].to; 58 if (e[i].cap > 0 && dep[v] == dep[u] + 1 && (temp = DFS(v, min(minx, e[i].cap)))) { 59 e[i].cap -= temp; 60 e[i ^ 1].cap += temp; 61 return temp; 62 } 63 } 64 return 0; 65 } 66 67 int Dinic() { 68 int ans = 0, temp; 69 while (BFS()) { 70 while (true) { 71 temp = DFS(src, INF); 72 if (temp <= 0) break; 73 ans += temp; 74 } 75 } 76 return ans; 77 } 78 79 void Solve() { 80 int temp=Dinic(); 81 for (int i = 0; i < tot; i += 2) { 82 if (!e[i].cap) 83 e[i].cap = 1; 84 else 85 e[i].cap = INF; 86 e[i ^ 1].cap = 0; 87 } 88 int ans = Dinic(); 89 printf_s("%d\n", ans); 90 } 91 92 int main() 93 { 94 scanf_s("%d", &kase); 95 for (int t = 1; t <= kase; t++) { 96 scanf_s("%d%d", &n, &m); 97 Inite(); 98 for (int i = 1; i <= m; i++) { 99 int u, v, w, d; 100 scanf_s("%d%d%d%d", &u, &v, &w, &d); 101 addedge(u, v, w); 102 if (d) addedge(v, u, w); 103 } 104 printf_s("Case %d: ", t); 105 Solve(); 106 } 107 return 0; 108 }

浙公网安备 33010602011771号