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; }

  • 相关阅读:
    分享Kali Linux 2016.2第41周镜像虚拟机
    Visual Studio工具栏中无法选择调试设备
    Xamarin.iOS编译出错
    Xamarin基础命名空间Microsoft.SqlServer.Server
    编译包含Google Play服务App的SDK版本问题
    解决Fiddler无法抓到手机的会话包
    Xamarin.Android编译CPU类型选择方式
    Delphi iOS
    Delphi Android
    CRC16-循环冗余校验
  • 原文地址:https://www.cnblogs.com/orangeko/p/12639171.html
Copyright © 2011-2022 走看看