最小路径覆盖问题网络流24题
Posted orangeko
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了最小路径覆盖问题网络流24题相关的知识,希望对你有一定的参考价值。
输入输出样例
11 12 1 2 1 3 1 4 2 5 3 6 4 7 5 8 6 9 7 10 8 11 9 11 10 11
1 4 7 10 11 2 5 8 3 6 9 3
说明/提示
1leq nleq 150,1leq mleq 60001≤n≤150,1≤m≤6000
由@FlierKing提供SPJ
思路
既然是网络流24中的题目,就从网络流的方法下手吧。
对于样例来说
其实不难看出这题是和流的路径有关的。
为了保证每个点只能用一次,
可以考虑把每个点拆成出入两个点,
它们之间的通道容量为1.
由于起点终点的不确定,
对整张图建立源点和汇点即可。
CODE
1 #include <bits/stdc++.h> 2 #define dbg(x) cout << #x << "=" << x << endl 3 #define eps 1e-8 4 #define pi acos(-1.0) 5 6 using namespace std; 7 typedef long long LL; 8 9 const int inf = 0x3f3f3f3f; 10 11 template<class T>inline void read(T &res) 12 { 13 char c;T flag=1; 14 while((c=getchar())<‘0‘||c>‘9‘)if(c==‘-‘)flag=-1;res=c-‘0‘; 15 while((c=getchar())>=‘0‘&&c<=‘9‘)res=res*10+c-‘0‘;res*=flag; 16 } 17 18 namespace _buff { 19 const size_t BUFF = 1 << 19; 20 char ibuf[BUFF], *ib = ibuf, *ie = ibuf; 21 char getc() { 22 if (ib == ie) { 23 ib = ibuf; 24 ie = ibuf + fread(ibuf, 1, BUFF, stdin); 25 } 26 return ib == ie ? -1 : *ib++; 27 } 28 } 29 30 int qread() { 31 using namespace _buff; 32 int ret = 0; 33 bool pos = true; 34 char c = getc(); 35 for (; (c < ‘0‘ || c > ‘9‘) && c != ‘-‘; c = getc()) { 36 assert(~c); 37 } 38 if (c == ‘-‘) { 39 pos = false; 40 c = getc(); 41 } 42 for (; c >= ‘0‘ && c <= ‘9‘; c = getc()) { 43 ret = (ret << 3) + (ret << 1) + (c ^ 48); 44 } 45 return pos ? ret : -ret; 46 } 47 48 const int maxn = 2e4 + 7; 49 50 int s, t, cnt; 51 int head[maxn << 1], edge[maxn << 1], nxt[maxn << 1], vis[maxn << 1]; 52 int w[maxn << 1];//残量网络 53 int rev[maxn << 1]; 54 int depth[maxn << 1];//图层 55 int n, m; 56 57 void BuildGraph(int u, int v, int cap) { 58 ++cnt; 59 edge[cnt] = v; 60 nxt[cnt] = head[u]; 61 rev[cnt] = cnt + 1; 62 w[cnt] = cap; 63 head[u] = cnt; 64 65 ++cnt; 66 edge[cnt] = u; 67 nxt[cnt] = head[v]; 68 w[cnt] = 0; 69 rev[cnt] = cnt - 1; 70 head[v] = cnt; 71 } 72 73 bool bfs(int x) { 74 queue<int> q; 75 while(!q.empty()) { 76 q.pop(); 77 } 78 memset(depth, 63, sizeof(depth)); 79 depth[s] = 0; 80 q.push(s); 81 do { 82 int u = q.front(); 83 q.pop(); 84 for ( int i = head[u]; i; i = nxt[i] ) { 85 int v = edge[i]; 86 if(w[i] > 0 && depth[u] + 1 < depth[v]) { 87 depth[v] = depth[u] + 1; 88 q.push(v); 89 if(v == t) { 90 return true; 91 } 92 } 93 } 94 } while (!q.empty()); 95 return false; 96 } 97 98 int dfs(int u, int dist) { 99 if(u == t) { 100 return dist; 101 } 102 for ( int i = head[u]; i; i = nxt[i] ) { 103 int v = edge[i]; 104 if(depth[v] == depth[u] + 1 && w[i] > 0) { 105 int di = dfs(v, min(dist, w[i])); 106 if(di > 0) { 107 w[i] -= di; 108 w[rev[i]] += di; 109 vis[u] = v; 110 //printf("vis[%d]:%d ",u, v); 111 return di; 112 } 113 } 114 } 115 return 0; 116 } 117 118 int main() 119 { 120 //freopen("data.txt", "r", stdin); 121 memset(vis, 0, sizeof(vis)); 122 read(n); read(m); 123 s = 0, t = 2 * n + 1; 124 for ( int i = 1; i <= m; ++i ) { 125 int u, v; 126 read(u); read(v); 127 BuildGraph(u, v + n, 1); 128 } 129 for ( int i = 1; i <= n; ++i ) { 130 BuildGraph(s, i, 1); 131 BuildGraph(n + i, t, 1); 132 } 133 int ans = 0; 134 while(bfs(s)) { 135 //cout << "!" << endl; 136 int res = dfs(0, 0x7f7f7f7f); 137 ans += res; 138 } 139 for ( int i = 1; i <= n; ++i ) { 140 if(vis[i]) { 141 int temp = i; 142 do { 143 if(temp > n) { 144 temp -= n; 145 } 146 printf("%d ",temp); 147 int x = vis[temp]; 148 vis[temp] = 0; 149 temp = x; 150 } while (temp != 0); 151 puts(""); 152 } 153 } 154 printf("%d ",n - ans); 155 return 0; 156 }
usingnamespacestd; typedeflonglong LL; constint inf = 0x3f3f3f3f; template<class T>inline void read(T &res) {char c;T flag=1; while((c=getchar())<‘0‘||c>‘9‘)if(c==‘-‘)flag=-1;res=c-‘0‘; while((c=getchar())>=‘0‘&&c<=‘9‘)res=res*10+c-‘0‘;res*=flag; } namespace _buff { constsize_t BUFF = 1 << 19; char ibuf[BUFF], *ib = ibuf, *ie = ibuf; char getc() { if (ib == ie) { ib = ibuf; ie = ibuf + fread(ibuf, 1, BUFF, stdin); } return ib == ie ? -1 : *ib++; } } int qread() { usingnamespace _buff; int ret = 0; bool pos = true; char c = getc(); for (; (c < ‘0‘ || c > ‘9‘) && c != ‘-‘; c = getc()) { assert(~c); } if (c == ‘-‘) { pos = false; c = getc(); } for (; c >= ‘0‘ && c <= ‘9‘; c = getc()) { ret = (ret << 3) + (ret << 1) + (c ^ 48); } return pos ? ret : -ret; } constint maxn = 2e4 + 7; int s, t, cnt; int head[maxn << 1], edge[maxn << 1], nxt[maxn << 1], vis[maxn << 1]; int w[maxn << 1];//残量网络int rev[maxn << 1]; int depth[maxn << 1];//图层int n, m; void BuildGraph(int u, int v, int cap) { ++cnt; edge[cnt] = v; nxt[cnt] = head[u]; rev[cnt] = cnt + 1; w[cnt] = cap; head[u] = cnt; ++cnt; edge[cnt] = u; nxt[cnt] = head[v]; w[cnt] = 0; rev[cnt] = cnt - 1; head[v] = cnt; } bool bfs(int x) { queue<int> q; while(!q.empty()) { q.pop(); } memset(depth, 63, sizeof(depth)); depth[s] = 0; q.push(s); do { int u = q.front(); q.pop(); for ( int i = head[u]; i; i = nxt[i] ) { int v = edge[i]; if(w[i] > 0 && depth[u] + 1 < depth[v]) { depth[v] = depth[u] + 1; q.push(v); if(v == t) { returntrue; } } } } while (!q.empty()); returnfalse; } int dfs(int u, int dist) { if(u == t) { return dist; } for ( int i = head[u]; i; i = nxt[i] ) { int v = edge[i]; if(depth[v] == depth[u] + 1 && w[i] > 0) { int di = dfs(v, min(dist, w[i])); if(di > 0) { w[i] -= di; w[rev[i]] += di; vis[u] = v; //printf("vis[%d]:%d ",u, v);return di; } } } return0; } int main() { //freopen("data.txt", "r", stdin);memset(vis, 0, sizeof(vis)); read(n); read(m); s = 0, t = 2 * n + 1; for ( int i = 1; i <= m; ++i ) { int u, v; read(u); read(v); BuildGraph(u, v + n, 1); } for ( int i = 1; i <= n; ++i ) { BuildGraph(s, i, 1); BuildGraph(n + i, t, 1); } int ans = 0; while(bfs(s)) { //cout << "!" << endl;int res = dfs(0, 0x7f7f7f7f); ans += res; } for ( int i = 1; i <= n; ++i ) { if(vis[i]) { int temp = i; do { if(temp > n) { temp -= n; } printf("%d ",temp); int x = vis[temp]; vis[temp] = 0; temp = x; } while (temp != 0); puts(""); } } printf("%d ",n - ans); return0; }
以上是关于最小路径覆盖问题网络流24题的主要内容,如果未能解决你的问题,请参考以下文章