zoukankan      html  css  js  c++  java
  • 最小路径覆盖问题【网络流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

    说明/提示

    1leq nleq 150,1leq mleq 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
    ",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 }
    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 ",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; }

  • 相关阅读:
    [LeetCode 1029] Two City Scheduling
    POJ 2342 Anniversary party (树形DP入门)
    Nowcoder 106 C.Professional Manager(统计并查集的个数)
    2018 GDCPC 省赛总结
    CF 977 F. Consecutive Subsequence
    Uva 12325 Zombie's Treasure Chest (贪心,分类讨论)
    Poj 2337 Catenyms(有向图DFS求欧拉通路)
    POJ 1236 Network of Schools (强连通分量缩点求度数)
    POJ 1144 Network (求割点)
    POJ 3310 Caterpillar(图的度的判定)
  • 原文地址:https://www.cnblogs.com/orangeko/p/12639171.html
Copyright © 2011-2022 走看看