最小路径覆盖问题【网络流24题】

 

 

输入输出样例

输入 #1
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
1 4 7 10 11
2 5 8
3 6 9
3

说明/提示

1\leq n\leq 150,1\leq m\leq 60001n150,1m6000

由@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\n",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",n - ans);
155     return 0;
156 }
View Code

#include <bitsst#define dbg(x) cout << #x << "=" << x << endl#define eps 1e-8#define pi acos(-1.0)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\n",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",n - ans); return0; }

posted @ 2020-04-05 21:26  Orangeko  阅读(139)  评论(0编辑  收藏  举报