zoukankan      html  css  js  c++  java
  • P2764 最小路径覆盖问题 (最小点覆盖=顶点数-最大匹配)

    题意:最小路径覆盖

    题解:对于一个有向图,最小点覆盖 = 顶点数 - 最大匹配

       这里的最大匹配指的是将原图中每一个点拆成入点、出点, 每条边连接起点的出点和终点的入点

       源点S连接每个点的出点,汇点T连接每个点的入点,这样建出来的二分图的最大匹配

       然后输出路径被坑了很久 因为自己拆点的标号问题吧

       我的拆点方式入点是偶数 出点是奇数 然后特判哪里就要写清楚

    #include <bits/stdc++.h>
    using namespace std;
    const int INF = 0x3f3f3f3f;
    int n, m, s, t, cnt, maxflow;
    
    struct node {
        int to, nex, val;
    }E[20005];
    int head[305];
    int cur[305];
    
    void addedge(int x, int y, int va) {
        E[++cnt].to = y; E[cnt].nex = head[x]; head[x] = cnt; E[cnt].val = va;
        E[++cnt].to = x; E[cnt].nex = head[y]; head[y] = cnt; E[cnt].val = 0;
    }
    
    int inque[305];
    int dep[305];
    int to[305];
    bool bfs() {
        for(int i = 0; i <= n * 2 + 1; i++) cur[i] = head[i], inque[i] = 0, dep[i] = INF;
        queue<int> que;
        dep[s] = 0; inque[s] = 1;
        que.push(s);
    
        while(!que.empty()) {
            int u = que.front();
            que.pop();
            inque[u] = 0;
    
            for(int i = head[u]; i; i = E[i].nex) {
                int v = E[i].to;
                if(E[i].val > 0 && dep[v] > dep[u] + 1) {
                    dep[v] = dep[u] + 1;
                    if(!inque[v]) {
                        inque[v] = 1;
                        que.push(v);
                    }
                }
            }
        }
        if(dep[t] != INF) return true;
        return false;
    }
    
    int vis;
    int viss[155];
    int dfs(int x, int flow) {
        if(x == t) {
            vis = 1;
            maxflow += flow;
            return flow;
        }
    
        int used = 0;
        int rflow = 0;
        for(int i = cur[x]; i; i = E[i].nex) {
            cur[x] = i;
            int v = E[i].to;
            if(E[i].val > 0 && dep[v] == dep[x] + 1) {
                if(rflow = dfs(v, min(flow - used, E[i].val))) {
                    if(v != t && x != s && (x % 2 == 0) && (v % 2 == 1)) to[x / 2] = v / 2, viss[v / 2] = 1;
                    used += rflow;
                    E[i].val -= rflow;
                    E[i ^ 1].val += rflow;
                    if(used == flow) break;
                }
            }
        }
        return used;
    }
    
    void dinic() {
        maxflow = 0;
        while(bfs()) {
            vis = 1;
            while(vis) {
                vis = 0;
                dfs(s, INF);
            }
        }
    }
    
    int main() {
        scanf("%d%d", &n, &m);
        s = 0, t = 1;
        cnt = 1;
        for(int i = 1; i <= n; i++) {
            addedge(s, i << 1, 1);
            addedge(i << 1 | 1, t, 1);
        }
    
        for(int i = 1; i <= m; i++) {
            int a, b;
            scanf("%d%d", &a, &b);
            addedge(a << 1, b << 1 | 1, INF);
        }
        dinic();
        int ans = n - maxflow;
        for(int i = 1; i <= n; i++) {
            if(!viss[i]) {
                printf("%d", i);
                for(int j = to[i]; j; j = to[j]) printf(" %d", j);
                puts("");
            }
        }
        printf("%d
    ", ans);
        return 0;
    }
    View Code
  • 相关阅读:
    (07)使用WireMock快速伪造REST服务
    (06)使用Swagger自动生成html文档,描述API接口
    (05)使用DeferredResult多线程异步处理请求
    (04)Spring开发中的3种拦截机制
    (03)使用SpringBoot自定义Restful风格异常处理,返回json格式数据
    (02)Restful风格的增删改查、上传、下载案例及其junit测试详解
    (01)Restful简介
    (03)maven项目分模块开发,子项目继承自父项目,打包运行方法
    (018)Spring Boot之常用配置
    (031)Spring Boot之服务的注册与发现,使用zookeeper演示负载均衡
  • 原文地址:https://www.cnblogs.com/lwqq3/p/11163133.html
Copyright © 2011-2022 走看看