zoukankan      html  css  js  c++  java
  • [luoguP2764] 最小路径覆盖问题(最大流 || 二分图最大匹配)

    传送门

    可惜洛谷上没有special judge,不然用匈牙利也可以过的,因为匈牙利在增广上有一个顺序问题,所以没有special judge就过不了了。

    好在这个题的测试数据比较特殊,如果是网络流的话按照顺序加边,就可以过。

    最小不相交路径覆盖 = 总点数 - 最大匹配数

    ——代码

      1 #include <queue>
      2 #include <cstdio>
      3 #include <cstring>
      4 #include <iostream>
      5 #define N 20001
      6 #define min(x, y) ((x) < (y) ? (x) : (y))
      7 #define max(x, y) ((x) > (y) ? (x) : (y))
      8 
      9 int n, m, cnt, sum, s, t;
     10 int head[N], belong[N], to[N], next[N], val[N], suc[N], cur[N], dis[N];
     11 
     12 inline int read()
     13 {
     14     int x = 0, f = 1;
     15     char ch = getchar();
     16     for(; !isdigit(ch); ch = getchar()) if(ch == '-') f = -1;
     17     for(; isdigit(ch); ch = getchar()) x = (x << 1) + (x << 3) + ch - '0';
     18     return x * f;
     19 }
     20 
     21 inline void add(int x, int y, int z)
     22 {
     23     to[cnt] = y;
     24     val[cnt] = z;
     25     next[cnt] = head[x];
     26     head[x] = cnt++;
     27 }
     28 
     29 inline bool bfs()
     30 {
     31     int i, u, v;
     32     std::queue <int> q;
     33     memset(dis, -1, sizeof(dis));
     34     q.push(s);
     35     dis[s] = 0;
     36     while(!q.empty())
     37     {
     38         u = q.front(), q.pop();
     39         for(i = head[u]; i ^ -1; i = next[i])
     40         {
     41             v = to[i];
     42             if(val[i] && dis[v] == -1)
     43             {
     44                 dis[v] = dis[u] + 1;
     45                 if(v == t) return 1;
     46                 q.push(v);
     47             }
     48         }
     49     }
     50     return 0;
     51 }
     52 
     53 inline int dfs(int u, int maxflow)
     54 {
     55     if(u == t) return maxflow;
     56     int i, v, d, ret = 0;
     57     for(i = cur[u]; i ^ -1; i = next[i])
     58     {
     59         v = to[i];
     60         if(val[i] && dis[v] == dis[u] + 1)
     61         {
     62             d = dfs(v, min(val[i], maxflow - ret));
     63             ret += d;
     64             cur[u] = i;
     65             val[i] -= d;
     66             val[i ^ 1] += d;
     67             if(d) suc[u] = v - n;
     68             if(ret == maxflow) return ret;
     69         }
     70     }
     71     return ret;
     72 }
     73 
     74 int main()
     75 {
     76     int i, j, x, y, now;
     77     n = read();
     78     m = read();
     79     s = 0, t = (n << 1) + 1;
     80     memset(head, -1, sizeof(head));
     81     for(i = 1; i <= m; i++)
     82     {
     83         x = read();
     84         y = read();
     85         add(x, y + n, 1);
     86         add(y + n, x, 0);
     87     }
     88     for(i = 1; i <= n; i++)
     89     {
     90         add(s, i, 1);
     91         add(i, s, 0);
     92         add(i + n, t, 1);
     93         add(t, i + n, 0);
     94     }
     95     while(bfs())
     96     {
     97         for(i = s; i <= t; i++) cur[i] = head[i];
     98         sum += dfs(s, 1e9);
     99     }
    100     for(i = 1; i <= n; i++)
    101         if(suc[i])
    102         {
    103             now = i;
    104             while(now)
    105             {
    106                 printf("%d ", now);
    107                 x = suc[now];
    108                 suc[now] = 0;
    109                 now = x;
    110             }
    111             puts("");
    112         }
    113     printf("%d
    ", n - sum);
    114     return 0;
    115 }
    View Code
  • 相关阅读:
    异常练习一 throw
    MAP排序
    Java正则表达式应用详解
    java多线程 sleep()和wait()的区别
    面向对象的15、18位中国大陆身份证号码解析、工具
    java学习笔记--this 关键字的理解
    Java六大问题你都懂了吗?
    Java类的声明和访问介绍
    java的五种数据类型解析
    Java集合框架的总结
  • 原文地址:https://www.cnblogs.com/zhenghaotian/p/6930560.html
Copyright © 2011-2022 走看看