最近网络流AC题目总结(水题版)
1.【模板】网络最大流
这个题目是模板啊,没什么好总结的,只要会EK或Dinic或Isap就可以了,我不会Isap啊,代码什么的在这里点击 我是链接
2. [USACO4.2]草地排水Drainage Ditches
这个题依然是模板啊,m是点,n是边,跑1到n的最短路就A了啊
1 // luogu-judger-enable-o2 2 #include <map> 3 #include <set> 4 #include <cmath> 5 #include <ctime> 6 #include <queue> 7 #include <stack> 8 #include <vector> 9 #include <bitset> 10 #include <cstdio> 11 #include <cctype> 12 #include <string> 13 #include <cstring> 14 #include <cassert> 15 #include <climits> 16 #include <cstdlib> 17 #include <iostream> 18 #include <algorithm> 19 #include <functional> 20 using namespace std ; 21 22 #define rep(i, a, b) for (int (i)=(a);(i)<=(b);(i)++) 23 #define Rep(i, a, b) for (int (i)=(a)-1;(i)<(b);(i)++) 24 #define REP(i, a, b) for (int (i)=(a);(i)>=(b);(i)--) 25 #define reg(i, x) for (int (i)=head[x];(i);i=e[i].next) 26 #define clr(a) memset(a,0,sizeof(a)) 27 #define Sort(a, len) sort(a + 1, a + len + 1) 28 #define Sort2(a, len, cmp) sort(a + 1, a + len + 1, cmp) 29 #define ass(a, sum) memset(a, sum, sizeof(a)) 30 31 #define ull unsigned long long 32 #define ll long long 33 #define ls ((rt) << 1) 34 #define rs ((rt) << 1 | 1) 35 #define mp make_pair 36 #define pb push_back 37 #define fi first 38 #define se second 39 #define endl '\n' 40 #define Pii pair<int, int> 41 42 const int N = 100010 ; 43 const int iinf = INT_MAX/2 ; 44 const ll linf = LLONG_MAX/2 ; 45 const int MOD = 1e9+7 ; 46 47 inline int read(){ 48 int X = 0,w = 0 ; 49 char ch = 0; 50 while(!isdigit(ch)) {w |= ch == '-';ch = getchar();} 51 while(isdigit(ch)) X = (X<<3) + (X<<1) + (ch ^ 48),ch = getchar(); 52 return w ? -X : X; 53 } 54 55 void write(int x){ 56 if(x < 0) putchar('-'),x = -x; 57 if(x > 9) write(x / 10); 58 putchar(x%10 + '0'); 59 } 60 61 void print(int x) { 62 cout << x << endl ; 63 exit(0) ; 64 } 65 66 struct edge { 67 int to, nxt, w ; 68 } e[N << 1]; 69 70 int head[N], dep[N] ; 71 int n, m, s, t, top = 1 ; 72 73 void add(int a, int b, int w) { 74 e[++top] = (edge) {b, head[a], w} ; 75 head[a] = top ; 76 } 77 78 bool bfs() { //分层图 79 queue <int> q ; 80 q.push(s) ; 81 clr(dep) ; 82 dep[s] = 1 ; 83 while (!q.empty()) { 84 int now = q.front() ; 85 q.pop() ; 86 for (int i = head[now]; i; i = e[i].nxt) { 87 int to = e[i].to ; 88 if (e[i].w && !dep[to]) { 89 dep[to] = dep[now] + 1 ; 90 q.push(to) ; 91 } 92 } 93 } 94 if (!dep[t]) return 0 ; 95 else return 1 ; 96 } 97 98 int dfs(int rt, int dis) { 99 if (rt == t) return dis ; 100 for (int i = head[rt]; i; i = e[i].nxt) { 101 int to = e[i].to ; 102 if (dep[to] == dep[rt] + 1 && e[i].w) { 103 int p = dfs(to, min(dis, e[i].w)) ; 104 if (p) { 105 e[i].w -= p ; 106 e[i ^ 1].w += p ; 107 return p ; 108 } 109 } 110 } 111 return 0 ; 112 } 113 114 int Dinic() { 115 int ans = 0 ; 116 while (bfs()) { 117 while (int d = dfs(s, iinf)) ans += d ; 118 } 119 return ans ; 120 } 121 122 int main() { 123 scanf("%d%d", &m, &n) ; 124 s = 1, t = n ; 125 for (int i = 1; i <= m; i++) { 126 int a, b, c ; 127 scanf("%d%d%d", &a, &b, &c) ; 128 add(a, b, c) ; 129 add(b, a, 0) ; 130 } 131 printf("%d\n", Dinic()) ; 132 }
3. 酒店之王
这个题目是我第一个正经的网络流题,而且是一个二分图最大匹配。。
我们把人放在房间和菜中间,建一个二分图,图的示意如下:
图中每条边的边权为1,之后再跑网络流(Dinic)即可。
1 #include <map> 2 #include <set> 3 #include <cmath> 4 #include <ctime> 5 #include <queue> 6 #include <stack> 7 #include <vector> 8 #include <bitset> 9 #include <cstdio> 10 #include <cctype> 11 #include <string> 12 #include <cstring> 13 #include <cassert> 14 #include <climits> 15 #include <cstdlib> 16 #include <iostream> 17 #include <algorithm> 18 #include <functional> 19 using namespace std ; 20 21 #define rep(i, a, b) for (int (i)=(a);(i)<=(b);(i)++) 22 #define Rep(i, a, b) for (int (i)=(a)-1;(i)<(b);(i)++) 23 #define REP(i, a, b) for (int (i)=(a);(i)>=(b);(i)--) 24 #define reg(i, x) for (int (i)=head[x];(i);i=e[i].next) 25 #define clr(a) memset(a,0,sizeof(a)) 26 #define Sort(a, len) sort(a + 1, a + len + 1) 27 #define Sort2(a, len, cmp) sort(a + 1, a + len + 1, cmp) 28 #define ass(a, sum) memset(a, sum, sizeof(a)) 29 30 #define ull unsigned long long 31 #define ll long long 32 #define ls ((rt) << 1) 33 #define rs ((rt) << 1 | 1) 34 #define mp make_pair 35 #define pb push_back 36 #define fi first 37 #define se second 38 #define endl '\n' 39 #define Pii pair<int, int> 40 41 const int N = 5000 ; 42 const int iinf = INT_MAX/2 ; 43 const ll linf = LLONG_MAX/2 ; 44 const int MOD = 1e9+7 ; 45 46 inline int read(){ 47 int X = 0,w = 0 ; 48 char ch = 0; 49 while(!isdigit(ch)) {w |= ch == '-';ch = getchar();} 50 while(isdigit(ch)) X = (X<<3) + (X<<1) + (ch ^ 48),ch = getchar(); 51 return w ? -X : X; 52 } 53 54 void write(int x){ 55 if(x < 0) putchar('-'),x = -x; 56 if(x > 9) write(x / 10); 57 putchar(x%10 + '0'); 58 } 59 60 void print(int x) { 61 cout << x << endl ; 62 exit(0) ; 63 } 64 65 int head[N], dep[N], a[N], pre[N] ; 66 int top = 1, n, p, q, s, t, ans ; 67 68 struct edge { 69 int to, nxt, w ; 70 } e[N << 1]; 71 72 void add(int a, int b, int w) { 73 e[++top] = (edge) {b, head[a], w} ; 74 head[a] = top ; 75 } 76 77 bool bfs(){ 78 queue <int> q ; 79 clr(a) ; 80 a[s] = 0x3f3f3f3f ; 81 q.push(s) ; 82 while(!q.empty()){ 83 int now = q.front() ; 84 q.pop() ; 85 for(int i=head[now];i;i=e[i].nxt){ 86 int to = e[i].to ; 87 if(!e[i].w) continue ; 88 if(a[to]) continue ; 89 a[to] = min(a[now], e[i].w) ; 90 pre[to] = i ; 91 q.push(to) ; 92 } 93 } 94 if(!a[t]) return 0 ; 95 ans += a[t] ; 96 return 1 ; 97 } 98 99 void work(){ 100 for (int m = t; pre[m]; m = e[pre[m]^1].to) { 101 e[pre[m]].w -= a[t] ; 102 e[pre[m]^1].w += a[t] ; 103 } 104 } 105 106 void dinic() { 107 while (bfs()) work() ; 108 } 109 110 int main() { 111 scanf("%d%d%d", &n, &p, &q) ; 112 s = 2 * n + p + q + 1, t = s + 1 ; 113 for (int i = 1; i <= n; i++) 114 for (int j = 1; j <= p; j++) { 115 int x ; 116 scanf("%d", &x) ; 117 if (x ^ 1) continue ; 118 add(j, p + i, 1) ; 119 add(p + i, j, 0) ; 120 } 121 for (int i = 1; i <= n; i++) 122 for (int j = 1; j <= q; j++) { 123 int x ; 124 scanf("%d", &x) ; 125 if (x ^ 1) continue ; 126 add(p + n + q + i, p + n + j, 1) ; 127 add(p + n + j, p + n + q + i, 0) ; 128 } 129 for (int i = 1; i <= n; i++) { 130 add(p + i, p + n + q + i, 1) ; 131 add(p + n + q + i, p + i, 0) ; 132 } 133 for (int i = 1; i <= p; i++) { 134 add(s, i, 1) ; 135 add(i, s, 0) ; 136 } 137 for (int i = p + n + 1; i <= n + p + q; i++){ 138 add(i, t, 1) ; 139 add(t, i, 0) ; 140 } 141 dinic() ; 142 printf("%d\n", ans) ; 143 }
4.【模板】最小费用最大流
切了前一个紫题,感觉很有成就感,于是又去学新知识,感觉蛮简单的,就是把bfs改成spfa,但始终有一个疑问:能不能用dijkstra跑呢?
建边要从0或2这种细节就不用说了吧
1 #include <map> 2 #include <set> 3 #include <cmath> 4 #include <ctime> 5 #include <queue> 6 #include <stack> 7 #include <vector> 8 #include <bitset> 9 #include <cstdio> 10 #include <cctype> 11 #include <string> 12 #include <cstring> 13 #include <cassert> 14 #include <climits> 15 #include <cstdlib> 16 #include <iostream> 17 #include <algorithm> 18 #include <functional> 19 using namespace std ; 20 21 #define rep(i, a, b) for (int (i)=(a);(i)<=(b);(i)++) 22 #define Rep(i, a, b) for (int (i)=(a)-1;(i)<(b);(i)++) 23 #define REP(i, a, b) for (int (i)=(a);(i)>=(b);(i)--) 24 #define reg(i, x) for (int (i)=head[x];(i);i=e[i].next) 25 #define clr(a) memset(a,0,sizeof(a)) 26 #define Sort(a, len) sort(a + 1, a + len + 1) 27 #define Sort2(a, len, cmp) sort(a + 1, a + len + 1, cmp) 28 #define ass(a, sum) memset(a, sum, sizeof(a)) 29 30 #define ull unsigned long long 31 #define ll long long 32 #define ls ((rt) << 1) 33 #define rs ((rt) << 1 | 1) 34 #define mp make_pair 35 #define pb push_back 36 #define fi first 37 #define se second 38 #define endl '\n' 39 #define Pii pair<int, int> 40 41 const int N = 100100 ; 42 const int iinf = INT_MAX ; 43 const ll linf = LLONG_MAX/2 ; 44 const int MOD = 1e9+7 ; 45 46 inline int read(){ 47 int X = 0,w = 0 ; 48 char ch = 0; 49 while(!isdigit(ch)) {w |= ch == '-';ch = getchar();} 50 while(isdigit(ch)) X = (X<<3) + (X<<1) + (ch ^ 48),ch = getchar(); 51 return w ? -X : X; 52 } 53 54 void write(int x){ 55 if(x < 0) putchar('-'),x = -x; 56 if(x > 9) write(x / 10); 57 putchar(x%10 + '0'); 58 } 59 60 void print(int x) { 61 cout << x << endl ; 62 exit(0) ; 63 } 64 65 int top = 1, n, m, s, t, flow, costs ; 66 int head[N], dis[N], vis[N] ; 67 68 struct edge { 69 int to, nxt, w, f ; 70 } e[N << 1]; 71 72 void add(int a, int b, int w, int f) { 73 e[++top] = (edge) {b, head[a], w, f} ; 74 head[a] = top ; 75 } 76 77 struct fuckyou { 78 int x, id ; 79 } pre[N]; 80 81 bool spfa() { 82 clr(vis);clr(pre); 83 ass(dis,0x3f3f3f3f) ; 84 dis[s] = 0 ; 85 queue <int> q ; 86 q.push(s) ; 87 while (!q.empty()) { 88 int now = q.front() ; 89 vis[now] = 0 ; 90 q.pop() ; 91 for (int i = head[now]; i; i = e[i].nxt) { 92 int to = e[i].to ; 93 if (e[i].w && dis[to] > dis[now] + e[i].f) { 94 dis[to] = dis[now] + e[i].f ; 95 pre[to] = (fuckyou) {now, i} ; 96 if (!vis[to]) { 97 q.push(to) ; 98 vis[to] = 1 ; 99 } 100 } 101 } 102 } 103 return dis[t] != 0x3f3f3f3f ; 104 } 105 106 void ek() { 107 while (spfa()) { 108 // for (int i = 1; i <= n; i++) cout << dis[i] << " " ; 109 // cout << endl ; 110 int mi = iinf ; 111 for (int i = t; i != s; i = pre[i].x) mi = min(mi, e[pre[i].id].w) ; 112 for (int i = t; i != s; i = pre[i].x) { 113 e[pre[i].id].w -= mi ; 114 e[pre[i].id ^ 1].w += mi ; 115 } 116 flow += mi ; 117 costs += mi * dis[t] ; 118 } 119 } 120 121 int main() { 122 scanf("%d%d%d%d", &n, &m, &s, &t) ; 123 for (int i = 1; i <= m; i++) { 124 int a, b, w, f ; 125 scanf("%d%d%d%d", &a, &b, &w, &f) ; 126 add(a, b, w, f) ; 127 add(b, a, 0, -f) ; 128 } 129 // cout << "ok\n" ; 130 ek() ; 131 printf("%d %d\n", flow, costs) ; 132 }
5. [USACO09JAN]全流Total Flow
早上一起来,发现模板全忘光,赶紧打一个模板题。
从A到Z跑网络流即可,是个傻逼题
1 #include <map> 2 #include <set> 3 #include <cmath> 4 #include <ctime> 5 #include <queue> 6 #include <stack> 7 #include <vector> 8 #include <bitset> 9 #include <cstdio> 10 #include <cctype> 11 #include <string> 12 #include <cstring> 13 #include <cassert> 14 #include <climits> 15 #include <cstdlib> 16 #include <iostream> 17 #include <algorithm> 18 #include <functional> 19 using namespace std ; 20 21 #define rep(i, a, b) for (int (i)=(a);(i)<=(b);(i)++) 22 #define Rep(i, a, b) for (int (i)=(a)-1;(i)<(b);(i)++) 23 #define REP(i, a, b) for (int (i)=(a);(i)>=(b);(i)--) 24 #define reg(i, x) for (int (i)=head[x];(i);i=e[i].next) 25 #define clr(a) memset(a,0,sizeof(a)) 26 #define Sort(a, len) sort(a + 1, a + len + 1) 27 #define Sort2(a, len, cmp) sort(a + 1, a + len + 1, cmp) 28 #define ass(a, sum) memset(a, sum, sizeof(a)) 29 30 #define ull unsigned long long 31 #define ll long long 32 #define ls ((rt) << 1) 33 #define rs ((rt) << 1 | 1) 34 #define mp make_pair 35 #define pb push_back 36 #define fi first 37 #define se second 38 #define endl '\n' 39 #define Pii pair<int, int> 40 41 const int N = 500 ; 42 const int iinf = INT_MAX/2 ; 43 const ll linf = LLONG_MAX/2 ; 44 const int MOD = 1e9+7 ; 45 46 inline int read(){ 47 int X = 0,w = 0 ; 48 char ch = 0; 49 while(!isdigit(ch)) {w |= ch == '-';ch = getchar();} 50 while(isdigit(ch)) X = (X<<3) + (X<<1) + (ch ^ 48),ch = getchar(); 51 return w ? -X : X; 52 } 53 54 void write(int x){ 55 if(x < 0) putchar('-'),x = -x; 56 if(x > 9) write(x / 10); 57 putchar(x%10 + '0'); 58 } 59 60 void print(int x) { 61 cout << x << endl ; 62 exit(0) ; 63 } 64 65 int b[300], head[N], dep[N] ; 66 int top = 1, n = 0, m, s, t, ans ; 67 68 struct edge { 69 int to, nxt, w ; 70 } e[N << 1] ; 71 72 void add(int a, int b, int w) { 73 e[++top] = (edge) {b, head[a], w} ; 74 head[a] = top ; 75 } 76 77 bool bfs() { 78 queue <int> q ; 79 clr(dep) ; 80 dep[s] = 1 ; 81 q.push(s) ; 82 while (!q.empty()) { 83 int now = q.front() ; 84 q.pop() ; 85 for (int i = head[now]; i; i = e[i].nxt) { 86 int to = e[i].to ; 87 if (!dep[to] && e[i].w) { 88 dep[to] = dep[now] + 1 ; 89 q.push(to) ; 90 } 91 } 92 } 93 if (dep[t]) return 1 ; 94 return 0 ; 95 } 96 97 int dfs(int rt, int flow) { 98 if (rt == t) return flow ; 99 for (int i = head[rt]; i; i = e[i].nxt) { 100 int to = e[i].to ; 101 if (e[i].w && dep[to] == dep[rt] + 1) { 102 int p = dfs(to, min(flow, e[i].w)) ; 103 if (p) { 104 e[i].w -= p ; 105 e[i ^ 1].w += p ; 106 return p ; 107 } 108 } 109 } 110 return 0 ; 111 } 112 113 int dinic() { 114 while (bfs()) { 115 while (int tmp = dfs(s, iinf)) ans += tmp ; 116 } 117 return ans ; 118 } 119 120 int main() { 121 cin >> m ; 122 for (int i = 1; i <= m; i++) { 123 char A, B ; 124 int C ; 125 cin >> A >> B >> C ; 126 add(A, B, C) ; 127 add(B, A, 0) ; 128 } 129 s = 'A', t = 'Z' ; 130 printf("%d\n", dinic()) ; 131 }
6. [CQOI2014]危桥
这个题目也是很水的。
如果这个桥是危桥,建dis为2的边,否则为∞
然后把往返an次和bn次看成走2*an次和2*bn次,由源点向a1和b1连容量分别为2*an和2*bn的边,
再由a2和b2向汇点连容量分别为2*an和2*bn的边,判断最大流是否等于2(an+bn)。
注意坑点:从a1发出的流量有可能跑到b2处。所以还要再建一遍图,源点向a1,b2建边,
a2,b1向汇点建边,如果两次最大流都等于2(an+bn),那么有解。否则无解。
1 #include <map> 2 #include <set> 3 #include <cmath> 4 #include <ctime> 5 #include <queue> 6 #include <stack> 7 #include <vector> 8 #include <bitset> 9 #include <cstdio> 10 #include <cctype> 11 #include <string> 12 #include <cstring> 13 #include <cassert> 14 #include <climits> 15 #include <cstdlib> 16 #include <iostream> 17 #include <algorithm> 18 #include <functional> 19 using namespace std ; 20 21 #define rep(i, a, b) for (int (i)=(a);(i)<=(b);(i)++) 22 #define Rep(i, a, b) for (int (i)=(a)-1;(i)<(b);(i)++) 23 #define REP(i, a, b) for (int (i)=(a);(i)>=(b);(i)--) 24 #define reg(i, x) for (int (i)=head[x];(i);i=e[i].next) 25 #define clr(a) memset(a,0,sizeof(a)) 26 #define Sort(a, len) sort(a + 1, a + len + 1) 27 #define Sort2(a, len, cmp) sort(a + 1, a + len + 1, cmp) 28 #define ass(a, sum) memset(a, sum, sizeof(a)) 29 30 #define ull unsigned long long 31 #define ll long long 32 #define ls ((rt) << 1) 33 #define rs ((rt) << 1 | 1) 34 #define mp make_pair 35 #define pb push_back 36 #define fi first 37 #define se second 38 #define endl '\n' 39 #define Pii pair<int, int> 40 41 const int iinf = INT_MAX/2 ; 42 const ll linf = LLONG_MAX/2 ; 43 const int MOD = 1e9+7 ; 44 45 inline int read(){ 46 int X = 0,w = 0 ; 47 char ch = 0; 48 while(!isdigit(ch)) {w |= ch == '-';ch = getchar();} 49 while(isdigit(ch)) X = (X<<3) + (X<<1) + (ch ^ 48),ch = getchar(); 50 return w ? -X : X; 51 } 52 53 void write(int x){ 54 if(x < 0) putchar('-'),x = -x; 55 if(x > 9) write(x / 10); 56 putchar(x%10 + '0'); 57 } 58 59 60 inline char get() { 61 char c; while ((c = getchar()) != 'X' && c != 'O' && c != 'N'); 62 return c; 63 } 64 65 const int N = 2e4 + 5, M = 55, INF = 0x3f3f3f3f; 66 int n, A1, A2, An, B1, B2, Bn, ecnt, nxt[N], adj[N], go[N], cap[N], 67 S, T, len, que[N], lev[N]; 68 char s[M][M]; 69 70 void add_edge(int u, int v, int w) { 71 nxt[++ecnt] = adj[u]; adj[u] = ecnt; go[ecnt] = v; cap[ecnt] = w; 72 nxt[++ecnt] = adj[v]; adj[v] = ecnt; go[ecnt] = u; cap[ecnt] = 0; 73 } 74 75 bool bfs() { 76 int i; memset(lev, -1, sizeof(lev)); 77 lev[que[len = 1] = S] = 0; 78 for (i = 1; i <= len; i++) { 79 int u = que[i]; 80 for (int e = adj[u], v; e; e = nxt[e]) 81 if (cap[e] > 0 && lev[v = go[e]] == -1) { 82 lev[que[++len] = v] = lev[u] + 1; 83 if (v == T) return 1; 84 } 85 } 86 return 0; 87 } 88 89 int dinic(int u, int flow) { 90 if (u == T) return flow; 91 int res = 0, delta; 92 for (int e = adj[u], v; e; e = nxt[e]) 93 if (cap[e] > 0 && lev[u] < lev[v = go[e]]) { 94 delta = dinic(v, min(cap[e], flow - res)); 95 if (delta) { 96 cap[e] -= delta; cap[e ^ 1] += delta; 97 res += delta; if (res == flow) break; 98 } 99 } 100 if (res != flow) lev[u] = -1; 101 return res; 102 } 103 104 int solve() { 105 int ans = 0; 106 while (bfs()) ans += dinic(S, INF); 107 return ans; 108 } 109 110 void work() { 111 int i, j, res1, res2; 112 A1 = read() + 2; A2 = read() + 2; An = read(); 113 B1 = read() + 2; B2 = read() + 2; Bn = read(); 114 for (i = 1; i <= n; i++) for (j = 1; j <= n; j++) 115 s[i][j] = get(); S = 1; T = n + 2; 116 ecnt = 1; memset(adj, 0, sizeof(adj)); 117 for (i = 1; i <= n; i++) for (j = 1; j <= n; j++) { 118 if (i == j) continue; 119 if (s[i][j] == 'O') add_edge(i + 1, j + 1, 2); 120 else if (s[i][j] == 'N') add_edge(j + 1, i + 1, INF); 121 } 122 add_edge(S, A1, An << 1); add_edge(S, B1, Bn << 1); 123 add_edge(A2, T, An << 1); add_edge(B2, T, Bn << 1); 124 res1 = solve(); 125 ecnt = 1; memset(adj, 0, sizeof(adj)); 126 for (i = 1; i <= n; i++) for (j = 1; j <= n; j++) { 127 if (i == j) continue; 128 if (s[i][j] == 'O') add_edge(i + 1, j + 1, 2); 129 else if (s[i][j] == 'N') add_edge(j + 1, i + 1, INF); 130 } 131 add_edge(S, A1, An << 1); add_edge(S, B2, Bn << 1); 132 add_edge(A2, T, An << 1); add_edge(B1, T, Bn << 1); 133 res2 = solve(); 134 puts(res1 == (An + Bn << 1) && res2 == (An + Bn << 1) ? "Yes" : "No"); 135 } 136 137 int main() { 138 while (~scanf("%d", &n)) work(); 139 }
7. [USACO4.2]完美的牛栏The Perfect Stall
绿题!非常水!
二分图匹配,直接跑!
s向所有奶牛连边,奶牛向对应牛栏连边,牛栏向t连边,就过了
水啊。。
1 #include <map> 2 #include <set> 3 #include <cmath> 4 #include <ctime> 5 #include <queue> 6 #include <stack> 7 #include <vector> 8 #include <bitset> 9 #include <cstdio> 10 #include <cctype> 11 #include <string> 12 #include <cstring> 13 #include <cassert> 14 #include <climits> 15 #include <cstdlib> 16 #include <iostream> 17 #include <algorithm> 18 #include <functional> 19 using namespace std ; 20 21 #define rep(i, a, b) for (int (i)=(a);(i)<=(b);(i)++) 22 #define Rep(i, a, b) for (int (i)=(a)-1;(i)<(b);(i)++) 23 #define REP(i, a, b) for (int (i)=(a);(i)>=(b);(i)--) 24 #define reg(i, x) for (int (i)=head[x];(i);i=e[i].next) 25 #define clr(a) memset(a,0,sizeof(a)) 26 #define Sort(a, len) sort(a + 1, a + len + 1) 27 #define Sort2(a, len, cmp) sort(a + 1, a + len + 1, cmp) 28 #define ass(a, sum) memset(a, sum, sizeof(a)) 29 30 #define ull unsigned long long 31 #define ll long long 32 #define ls ((rt) << 1) 33 #define rs ((rt) << 1 | 1) 34 #define mp make_pair 35 #define pb push_back 36 #define fi first 37 #define se second 38 #define endl '\n' 39 #define Pii pair<int, int> 40 41 const int N = 500010 ; 42 const int iinf = INT_MAX/2 ; 43 const ll linf = LLONG_MAX/2 ; 44 const int MOD = 1e9+7 ; 45 46 inline int read(){ 47 int X = 0,w = 0 ; 48 char ch = 0; 49 while(!isdigit(ch)) {w |= ch == '-';ch = getchar();} 50 while(isdigit(ch)) X = (X<<3) + (X<<1) + (ch ^ 48),ch = getchar(); 51 return w ? -X : X; 52 } 53 54 void write(int x){ 55 if(x < 0) putchar('-'),x = -x; 56 if(x > 9) write(x / 10); 57 putchar(x%10 + '0'); 58 } 59 60 void print(int x) { 61 cout << x << endl ; 62 exit(0) ; 63 } 64 65 int top = 1, n, m, s, t ; 66 int head[N], dep[N] ; 67 68 struct edge { 69 int to, nxt, w ; 70 } e[N << 1] ; 71 72 void add(int a, int b, int w) { 73 e[++top] = (edge) {b, head[a], w} ; 74 head[a] = top ; 75 } 76 77 bool bfs() { 78 queue <int> q ; q.push(s) ; 79 memset(dep, 0, sizeof(dep)) ; 80 dep[s] = 1 ; 81 while (!q.empty()) { 82 int now = q.front() ; 83 q.pop() ; 84 for (int i = head[now]; i; i = e[i].nxt) { 85 int to = e[i].to ; 86 if (!dep[to] && e[i].w) { 87 dep[to] = dep[now] + 1 ; 88 q.push(to) ; 89 } 90 } 91 } 92 return dep[t] ? 1 : 0 ; 93 } 94 95 int dfs(int rt, int flow) { 96 if (rt == t) return flow ; 97 for (int i = head[rt]; i; i = e[i].nxt) { 98 int to = e[i].to ; 99 if (e[i].w && dep[to] == dep[rt] + 1) { 100 int p = dfs(to, min(flow, e[i].w)) ; 101 if (p) { 102 e[i].w -= p ; 103 e[i ^ 1].w += p ; 104 return p ; 105 } 106 } 107 } 108 return 0 ; 109 } 110 111 void dinic() { 112 int ans = 0 ; 113 while (bfs()) { 114 while (int d = dfs(s, 0x3f3f3f3f)) ans += d ; 115 } 116 printf("%d\n", ans) ; 117 } 118 119 int main() { 120 scanf("%d%d", &n, &m) ; 121 for (int i = 1; i <= n; i++) { 122 int sum, a ; 123 scanf("%d", &sum) ; 124 for (int j = 1; j <= sum; j++) { 125 scanf("%d", &a) ; 126 add(i, a + m, 1) ; 127 add(a + m, i, 0) ; 128 } 129 } 130 s = 0, t = n + m + 1 ; 131 for (int i = 1; i <= n; i++) { 132 add(s, i, 1) ; 133 add(i, s, 0) ; 134 } 135 for (int i = n + 1; i <= n + m; i++) { 136 add(i, t, 1) ; 137 add(t, i, 0) ; 138 } 139 dinic() ; 140 }
8. 地震逃生
又是一个最大流裸题,直接跑,设答案1位ans1,那么$ans2=\left\lceil\dfrac{x}{ans2}\right\rceil$,特判Orz Ni Jinan Saint Cow!的情况就AC了
1 #include <map> 2 #include <set> 3 #include <cmath> 4 #include <ctime> 5 #include <queue> 6 #include <stack> 7 #include <vector> 8 #include <bitset> 9 #include <cstdio> 10 #include <cctype> 11 #include <string> 12 #include <cstring> 13 #include <cassert> 14 #include <climits> 15 #include <cstdlib> 16 #include <iostream> 17 #include <algorithm> 18 #include <functional> 19 using namespace std ; 20 21 #define rep(i, a, b) for (int (i)=(a);(i)<=(b);(i)++) 22 #define Rep(i, a, b) for (int (i)=(a)-1;(i)<(b);(i)++) 23 #define REP(i, a, b) for (int (i)=(a);(i)>=(b);(i)--) 24 #define reg(i, x) for (int (i)=head[x];(i);i=e[i].next) 25 #define clr(a) memset(a,0,sizeof(a)) 26 #define Sort(a, len) sort(a + 1, a + len + 1) 27 #define Sort2(a, len, cmp) sort(a + 1, a + len + 1, cmp) 28 #define ass(a, sum) memset(a, sum, sizeof(a)) 29 30 #define ull unsigned long long 31 #define ll long long 32 #define ls ((rt) << 1) 33 #define rs ((rt) << 1 | 1) 34 #define mp make_pair 35 #define pb push_back 36 #define fi first 37 #define se second 38 #define endl '\n' 39 #define Pii pair<int, int> 40 41 const int N = 100010 ; 42 const int iinf = INT_MAX/2 ; 43 const ll linf = LLONG_MAX/2 ; 44 const int MOD = 1e9+7 ; 45 46 inline int read(){ 47 int X = 0,w = 0 ; 48 char ch = 0; 49 while(!isdigit(ch)) {w |= ch == '-';ch = getchar();} 50 while(isdigit(ch)) X = (X<<3) + (X<<1) + (ch ^ 48),ch = getchar(); 51 return w ? -X : X; 52 } 53 54 void write(int x){ 55 if(x < 0) putchar('-'),x = -x; 56 if(x > 9) write(x / 10); 57 putchar(x%10 + '0'); 58 } 59 60 void print(int x) { 61 cout << x << endl ; 62 exit(0) ; 63 } 64 65 struct edge { 66 int to, nxt, w ; 67 } e[N << 1] ; 68 69 int n, m, x, top = 1, s, t, ans ; 70 int dep[N], head[N] ; 71 72 void add(int a, int b, int w) { 73 e[++top] = (edge) {b, head[a], w} ; 74 head[a] = top ; 75 } 76 77 bool bfs() { 78 queue <int> q ; 79 q.push(s) ; 80 memset(dep, 0, sizeof(dep)) ; 81 dep[s] = 1 ; 82 while (!q.empty()) { 83 int now = q.front() ; 84 q.pop() ; 85 for (int i = head[now]; i; i = e[i].nxt){ 86 int to = e[i].to ; 87 if (!dep[to] && e[i].w) { 88 dep[to] = dep[now] + 1 ; 89 q.push(to) ; 90 } 91 } 92 } 93 if (!dep[t]) return 0 ; 94 else return 1 ; 95 } 96 97 int dfs(int rt, int flow) { 98 if (rt == t) return flow ; 99 for (int i = head[rt]; i; i = e[i].nxt) { 100 int to = e[i].to ; 101 if (dep[to] == dep[rt] + 1 && e[i].w) { 102 int p = dfs(to, min(flow, e[i].w)) ; 103 if (p) { 104 e[i].w -= p ; 105 e[i ^ 1].w += p ; 106 return p ; 107 } 108 } 109 } 110 return 0 ; 111 } 112 113 void dinic(){ 114 ans = 0 ; 115 while (bfs()) { 116 while (int d = dfs(s, iinf)) ans += d ; 117 } 118 } 119 120 int work(int a, int b) { 121 if (a % b != 0) return a / b + 1 ; 122 else return a / b ; 123 } 124 125 int main(){ 126 scanf("%d%d%d", &n, &m, &x) ; 127 for (int i = 1; i <= m; i++) { 128 int a, b, c ; 129 scanf("%d%d%d", &a, &b, &c) ; 130 add(a, b, c) ; 131 add(b, a, 0) ; 132 } 133 s = 1, t = n ; 134 dinic() ; 135 if (ans == 0) printf("Orz Ni Jinan Saint Cow!\n") ; 136 else printf("%d %d\n", ans, work(x, ans)) ; 137 }
9. 飞行员配对方案问题
没有发现原来这里还有一个水题。。。
直接跑网络流求二分图的模板,第二个匹配方案是这样解决的:
to!=s != t (to^1)!=s!=t && w print to && to ^ 1
ek好像没有这样的问题。
1 #include <map> 2 #include <set> 3 #include <cmath> 4 #include <ctime> 5 #include <queue> 6 #include <stack> 7 #include <vector> 8 #include <bitset> 9 #include <cstdio> 10 #include <cctype> 11 #include <string> 12 #include <cstring> 13 #include <cassert> 14 #include <climits> 15 #include <cstdlib> 16 #include <iostream> 17 #include <algorithm> 18 #include <functional> 19 using namespace std ; 20 21 #define rep(i, a, b) for (int (i)=(a);(i)<=(b);(i)++) 22 #define Rep(i, a, b) for (int (i)=(a)-1;(i)<(b);(i)++) 23 #define REP(i, a, b) for (int (i)=(a);(i)>=(b);(i)--) 24 #define reg(i, x) for (int (i)=head[x];(i);i=e[i].next) 25 #define clr(a) memset(a,0,sizeof(a)) 26 #define Sort(a, len) sort(a + 1, a + len + 1) 27 #define Sort2(a, len, cmp) sort(a + 1, a + len + 1, cmp) 28 #define ass(a, sum) memset(a, sum, sizeof(a)) 29 30 #define ull unsigned long long 31 #define ll long long 32 #define ls ((rt) << 1) 33 #define rs ((rt) << 1 | 1) 34 #define mp make_pair 35 #define pb push_back 36 #define fi first 37 #define se second 38 #define endl '\n' 39 #define Pii pair<int, int> 40 41 const int N = 100010 ; 42 const int iinf = INT_MAX/2 ; 43 const ll linf = LLONG_MAX/2 ; 44 const int MOD = 1e9+7 ; 45 46 inline int read(){ 47 int X = 0,w = 0 ; 48 char ch = 0; 49 while(!isdigit(ch)) {w |= ch == '-';ch = getchar();} 50 while(isdigit(ch)) X = (X<<3) + (X<<1) + (ch ^ 48),ch = getchar(); 51 return w ? -X : X; 52 } 53 54 void write(int x){ 55 if(x < 0) putchar('-'),x = -x; 56 if(x > 9) write(x / 10); 57 putchar(x%10 + '0'); 58 } 59 60 void print(int x) { 61 cout << x << endl ; 62 exit(0) ; 63 } 64 65 int n, m, s, t, top = 1, ans ; 66 int head[N], dep[N] ; 67 68 struct edge { 69 int to, nxt, w ; 70 } e[N << 1] ; 71 72 void add(int a, int b, int w) { 73 e[++top] = (edge) {b, head[a], w} ; 74 head[a] = top ; 75 } 76 77 bool bfs() { 78 queue <int> q ; 79 q.push(s) ; 80 memset(dep, 0, sizeof(dep)) ; 81 dep[s] = 1 ; 82 while (!q.empty()) { 83 int now = q.front() ; 84 q.pop() ; 85 for (int i = head[now]; i; i = e[i].nxt) { 86 int to = e[i].to ; 87 if (!dep[to] && e[i].w){ 88 dep[to] = dep[now] + 1 ; 89 q.push(to) ; 90 } 91 } 92 } 93 if (!dep[t]) return 0 ; 94 else return 1 ; 95 } 96 97 int dfs(int rt, int flow) { 98 if (rt == t) return flow ; 99 for (int i = head[rt]; i; i = e[i].nxt) { 100 int to = e[i].to ; 101 if (dep[to] == dep[rt] + 1 && e[i].w) { 102 int p = dfs(to, min(flow, e[i].w)) ; 103 if (p) { 104 e[i].w -= p ; 105 e[i ^ 1].w += p ; 106 return p ; 107 } 108 } 109 } 110 return 0 ; 111 } 112 113 void dinic() { 114 ans = 0 ; 115 while (bfs()) { 116 while (int d = dfs(s, iinf)) ans += d ; 117 } 118 } 119 120 int main(){ 121 scanf("%d%d", &n, &m) ; 122 int a, b ; 123 while (scanf("%d%d", &a, &b) && a != -1 && b != -1) { 124 add(a, b, 1) ; 125 add(b, a, 0) ; 126 } 127 s = 0, t = m + 1 ; 128 for (int i = 1; i <= n; i++) { 129 add(s, i, 1) ; 130 add(i, s, 0) ; 131 } 132 for (int i = n + 1; i <= m; i++) { 133 add(i, t, 1) ; 134 add(t, i, 0) ; 135 } 136 dinic() ; 137 if (!ans) printf("No Solution!\n") ; 138 else { 139 printf("%d\n", ans) ; 140 for (int i = 2; i <= top; i += 2) 141 if (e[i].to != s && e[i].to != t && e[i ^ 1].to != s && e[i ^ 1].to != t) 142 if (e[i ^ 1].w) printf("%d %d\n", e[i ^ 1].to, e[i].to) ; 143 } 144 }
10. 教辅的组成
拆点建边,和酒店之王差不多,不讲了
1 // luogu-judger-enable-o2 2 #include<iostream> 3 #include<cstdio> 4 #include<cstdlib> 5 #include<cmath> 6 #include<cstring> 7 #include<algorithm> 8 #include<queue> 9 using namespace std; 10 #define REP(i, a, b) for(register int i = (a), i##_end_ = (b); i <= i##_end_; ++ i) 11 #define DREP(i, a, b) for(register int i = (a), i##_end_ = (b); i >= i##_end_; -- i) 12 #define mem(a, b) memset((a), b, sizeof(a)) 13 int read() 14 { 15 int sum = 0, fg = 1; char c = getchar(); 16 while(c < '0' || c > '9') { if (c == '-') fg = -1; c = getchar(); } 17 while(c >= '0' && c <= '9') { sum = sum * 10 + c - '0'; c = getchar(); } 18 return sum * fg; 19 } 20 #define inf 0x3f3f3f3f 21 const int maxn = 1000000; 22 int e,be[maxn], ne[maxn], to[maxn], c[maxn]; 23 int nb, nex, na,m1,m2; 24 void add(int x, int y, int z) 25 { 26 to[e] = y, ne[e] = be[x], be[x] = e; 27 c[e] = z, e++; 28 to[e] = x, ne[e] = be[y], be[y] = e; 29 c[e] = 0, e++; 30 } 31 int d[maxn], end; 32 bool bfs() 33 { 34 queue<int>q; 35 memset(d,-1,sizeof(d)); 36 q.push(end),d[end] = 0; 37 while(!q.empty()) 38 { 39 int u = q.front(); q.pop(); 40 for(int i = be[u]; i!=-1; i = ne[i]) 41 { 42 int v = to[i]; 43 if(d[v] == -1 && c[i ^ 1]) 44 { 45 d[v] = d[u] + 1; 46 q.push(v); 47 } 48 } 49 } 50 return d[0]!=-1; 51 } 52 int dfs(int x,int low) 53 { 54 if(x == end || !low)return low; 55 int ret = 0; 56 for(int i = be[x]; i!=-1;i = ne[i]) 57 { 58 int v = to[i]; 59 if(d[v] == d[x] - 1 ) 60 { 61 int k = dfs(v,min(low-ret,c[i])); 62 if(k > 0) 63 { 64 c[i] -= k; 65 c[i^1] += k; 66 ret+=k; 67 } 68 } 69 } 70 return ret; 71 } 72 int dinic() 73 { 74 int ans = 0; 75 while(bfs()) 76 { 77 int k = dfs(0,inf); 78 if(k>0)ans+=k; 79 } 80 return ans; 81 } 82 int main() 83 { 84 memset(be,-1,sizeof(be)); 85 nb = read(); nex = read(); na = read(); 86 m1 = read(); 87 REP(i,1,m1) 88 { 89 int x,y; 90 x = read(), y = read(); 91 add(y,nex+x,1); 92 } 93 m2 = read(); 94 REP(i,1,m2) 95 { 96 int x,y; 97 x = read(), y = read(); 98 add(nex+nb+x,2*nb+nex+y,1); 99 } 100 end = 2*nb+nex+na+1; 101 REP(i,1,nex) add(0,i,1); 102 REP(i,1,na) add(2*nb+nex+i,end,1); 103 REP(i,1,nb) add(nex+i,nex+nb+i,1); 104 printf("%d",dinic()); 105 return 0; 106 }
thanks for your reading