思路:
二分+最大流。
实现:
1 #include <stdio.h> 2 #include <stdlib.h> 3 #include <limits.h> 4 #include <string.h> 5 #include <assert.h> 6 #include <queue> 7 #include <vector> 8 #include <algorithm> 9 #include <iostream> 10 11 #define N (398) 12 #define M (N * N + 4 * N) 13 const int INF = 0x3f3f3f3f; 14 typedef long long LL; 15 16 using namespace std; 17 18 struct edge 19 { 20 int v, cap, next; 21 }; 22 edge e[M]; 23 24 int head[N], level[N], cur[N]; 25 int num_of_edges; 26 27 void dinic_init(void) 28 { 29 num_of_edges = 0; 30 memset(head, -1, sizeof(head)); 31 return; 32 } 33 34 int add_edge(int u, int v, int c1, int c2) 35 { 36 int& i = num_of_edges; 37 38 assert(c1 >= 0 && c2 >= 0 && c1 + c2 >= 0); // check for possibility of overflow 39 e[i].v = v; 40 e[i].cap = c1; 41 e[i].next = head[u]; 42 head[u] = i++; 43 44 e[i].v = u; 45 e[i].cap = c2; 46 e[i].next = head[v]; 47 head[v] = i++; 48 return i; 49 } 50 51 int dfs(int u, int t, int bn) 52 { 53 if (u == t) return bn; 54 int left = bn; 55 for (int &i = cur[u]; i >= 0; i = e[i].next) 56 { 57 int v = e[i].v; 58 int c = e[i].cap; 59 if (c > 0 && level[u] + 1 == level[v]) 60 { 61 int flow = dfs(v, t, min(left, c)); 62 if (flow > 0) 63 { 64 e[i].cap -= flow; 65 e[i ^ 1].cap += flow; 66 cur[u] = i; 67 left -= flow; 68 if (!left) break; 69 } 70 } 71 } 72 if (left > 0) level[u] = 0; 73 return bn - left; 74 } 75 76 bool bfs(int s, int t) 77 { 78 memset(level, 0, sizeof(level)); 79 level[s] = 1; 80 queue<int> q; 81 q.push(s); 82 while (!q.empty()) 83 { 84 int u = q.front(); 85 q.pop(); 86 if (u == t) return true; 87 for (int i = head[u]; i >= 0; i = e[i].next) 88 { 89 int v = e[i].v; 90 if (!level[v] && e[i].cap > 0) 91 { 92 level[v] = level[u] + 1; 93 q.push(v); 94 } 95 } 96 } 97 return false; 98 } 99 100 LL dinic(int s, int t) 101 { 102 LL max_flow = 0; 103 104 while (bfs(s, t)) 105 { 106 memcpy(cur, head, sizeof(head)); 107 max_flow += dfs(s, t, INT_MAX); 108 } 109 return max_flow; 110 } 111 112 int n, p, t; 113 struct Edge 114 { 115 int a, b, cost; 116 }; 117 Edge es[40005]; 118 119 bool check(int x) 120 { 121 dinic_init(); 122 for (int i = 0; i < p; i++) 123 { 124 if (es[i].cost <= x) 125 { 126 add_edge(es[i].a, es[i].b, 1, 0); 127 add_edge(es[i].b, es[i].a, 1, 0); 128 } 129 } 130 return dinic(1, n) >= t; 131 } 132 133 int main() 134 { 135 scanf("%d %d %d", &n, &p, &t); 136 int maxn = 0; 137 for (int i = 0; i < p; i++) 138 { 139 scanf("%d %d %d", &es[i].a, &es[i].b, &es[i].cost); 140 maxn = max(maxn, es[i].cost); 141 } 142 int l = 0, r = maxn, ans = INF; 143 while (l <= r) 144 { 145 int m = (l + r) >> 1; 146 if (check(m)) 147 { 148 r = m - 1; ans = m; 149 } 150 else l = m + 1; 151 } 152 printf("%d\n", ans); 153 return 0; 154 }
原文地址:https://www.cnblogs.com/wangyiming/p/8280059.html
时间: 2024-10-15 11:59:41