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


    题目链接:最小路径覆盖问题

    哇 卡在输出也是醉了

    重要结论:最小路径覆盖数 = 结点数(拆成边之前) -  最大流

    本题也是点拆边

    与【网络流24题 #04】魔术球问题 

    有异曲同工之妙

    void output(int x){
        if(x >= S) return ;
        printf("%d ", x >> 1);
        for(int i = head[x]; i != -1; i = edge[i].next)
            if(!edge[i].w && edge[i].v < S) output(edge[i].v - 1);
    }   
    
    ……
    
    
     for(int i = 1; i <= n; i++) fa[i] = i;
        for(int i = 0; i <= esize; i += 2) {
            if(!edge[i].w && edge[i].v < S && edge[i].u < S){
                fa[find(edge[i].v >> 1)] = find(edge[i].u >> 1);        
            }
        }
        for(int i = 1; i <= n; i++){
            if(find(i) == i){
                output(i << 1);
                printf("
    ");
            }

    内心戏:(╯‵□′)╯︵┻━┻

    悄咪咪:居然还打扰H神吃饭…

      1 #include <cstdio>
      2 #include <algorithm>
      3 #include <queue>
      4 #include <cstring>
      5 #include <cmath>
      6 using namespace std;
      7 const int N = 4e4 + 5;
      8 const int inf = 0x3f3f3f3f;
      9 int n, m;
     10 struct Edge{
     11     int u, v, w, next;
     12 }edge[N << 1];
     13 int head[N], esize = -1;
     14 bool vis[N];
     15 int next[N], fa[N];
     16 inline void addedge(int x, int y, int z){
     17     edge[++esize] = (Edge){x, y, z, head[x]};
     18     head[x] = esize;
     19     edge[++esize] = (Edge){y, x, 0, head[y]};
     20     head[y] = esize;
     21 }
     22 queue<int> q;
     23 int dep[N];
     24 int S, T;
     25 
     26 bool bfs(){
     27     int fro;
     28     q.push(S); 
     29     memset(dep, 0, sizeof(dep));
     30     dep[S] = 1;
     31     while(!q.empty()){
     32         fro = q.front(); q.pop();
     33         for(int i = head[fro]; i != -1; i = edge[i].next){
     34             int vv = edge[i].v;
     35             if(!dep[vv] && edge[i].w > 0){
     36                 dep[vv] = dep[fro] + 1;
     37                 q.push(vv);
     38             }
     39         }
     40     }
     41     return dep[T];
     42 }
     43 
     44 int dfs(int x, int rest){
     45     if(x == T || !rest) return rest;
     46     for(int i = head[x], vv, ww, d; i != -1; i = edge[i].next){
     47         vv = edge[i].v, ww = edge[i].w;
     48         if(dep[vv] != dep[x] + 1) continue;
     49         d = dfs(vv, min(rest, ww));
     50         if(d > 0){
     51             edge[i].w -= d;
     52             edge[i ^ 1].w += d;
     53             return d;
     54         }
     55     }
     56     return 0;
     57 }
     58 
     59 int dinic(){
     60     int ret = 0;
     61     while(bfs()){
     62         ret += dfs(S, inf);
     63     }
     64     return ret;
     65 }
     66 
     67 int find(int x){
     68     return x == fa[x] ? x : fa[x] = find(fa[x]);
     69 }
     70 
     71 void output(int x){
     72     if(x >= S) return ;
     73     printf("%d ", x >> 1);
     74     for(int i = head[x]; i != -1; i = edge[i].next)
     75         if(!edge[i].w && edge[i].v < S) output(edge[i].v - 1);
     76 }
     77 
     78 int main(){
     79     scanf("%d%d", &n, &m);
     80     memset(head, -1, sizeof(head));
     81     memset(next, -1, sizeof(next));
     82     S = N - 3, T = N - 2;
     83     for(int i = 1; i <= n; i++){
     84         addedge(S, i << 1, 1);
     85         addedge(i << 1 | 1, T, 1);
     86     }
     87     for(int i = 1, x, y; i <= m; i++){
     88         addedge(x << 1, y << 1 | 1, 1);
     89     }
     90     int cnt = n - dinic();
     91     for(int i = 1; i <= n; i++) fa[i] = i;
     92     for(int i = 0; i <= esize; i += 2) {
     93         if(!edge[i].w && edge[i].v < S && edge[i].u < S){
     94             fa[find(edge[i].v >> 1)] = find(edge[i].u >> 1);
     95         }
     96     }
     97     for(int i = 1; i <= n; i++){
     98         if(find(i) == i){
     99             output(i << 1);
    100             printf("
    ");
    101         }
    102     }
    103     printf("%d", cnt);
    104     return 0;
    105 }
    Whole

     

  • 相关阅读:
    很漂亮的按钮css样式(没有用到图片,可直接拷贝代码使用)
    if、while中变量的作用域问题
    笔记
    搭建高可用mongodb集群(一)——配置mongodb
    Java编程:删除 List 元素的三种正确方法
    MySQL 数据类型
    MySQL 通用查询日志(General Query Log)
    mysql 创建一个用户,指定一个数据库
    MySQL 5.7 免安装版配置
    String,StringBuffer与StringBuilder的区别??
  • 原文地址:https://www.cnblogs.com/hjmmm/p/9278383.html
Copyright © 2020-2023  润新知