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


    最近在学网络流,老师叫我做这题,然后就A了。。

    原题地址:https://www.luogu.org/problem/show?pid=2764

    解题思路:网络流跑最大匹配,路径数就是节点数-匹配数。

    附代码:

    #include<cstdio>
    #include<iostream>
    #include<cstring>
    #include<string>
    #include<algorithm>
    #include<cmath>
    #define For(i,a,b) for (int i=a; i<=b; i++)
    #define Ford(i,a,b) for (int i=a; i>=b; i--)
    #define File(fn) freopen(fn".in","r",stdin); freopen(fn".out","w",stdout);
    #define mem(qaq,num) memset(qaq,num,sizeof(qaq));
    #define ll long long
    #define mod 1000000007
    #define INF 2000000000
    using namespace std;
    struct zxy{
        int next,to,v;
    }edge[2000001];
    int n,cnt=1,head[8001],lev[8001],to[8001],que[8001],m;
    bool b[4001];
    inline int in(){
        int x=0,f=1;
        char ch=getchar();
        while (ch<'0'||ch>'9') f=ch=='-'?-1:1,ch=getchar();
        while (ch>='0'&&ch<='9') x=x*10+ch-'0',ch=getchar();
        return x*f;
    }
    inline void ins(int x,int y,int l){
        edge[++cnt].to=y,edge[cnt].next=head[x],edge[cnt].v=l,head[x]=cnt;
        edge[++cnt].to=x,edge[cnt].next=head[y],edge[cnt].v=0,head[y]=cnt;
    }
    inline bool bfs(int s,int e){
        mem(lev,-1);
        int t=1,h=0;
        que[0]=s;
        lev[s]=0;
        do{
            h++;
            int k=head[que[h]];
            while(k){
                if (lev[edge[k].to]==-1&&edge[k].v){
                    lev[edge[k].to]=lev[que[h]]+1;
                    que[++t]=edge[k].to;
                }
                k=edge[k].next;
            }
        }while(h<t);
        return lev[e]!=-1;
    }
    inline int dfs(int u,int v,int f){
        if (u==v) return f;
        int used=0,k=head[u];
        while(k){
            if (edge[k].v&&lev[edge[k].to]==lev[u]+1){
                int w=dfs(edge[k].to,v,min(edge[k].v,f-used));
                if (w){
                    to[u]=edge[k].to;
                    if (edge[k].to>n) b[edge[k].to-n]=1;
                }
                used+=w;
                edge[k].v-=w;
                edge[k^1].v+=w;
                if (used==f) return used;
            }
            k=edge[k].next;
        }
        return used;
    }
    int dinic(int s,int t){
        int flow=0;
        while(bfs(s,t))
            flow+=dfs(s,t,INF);
        return flow;
    }
    void read(){
        n=in(),m=in();
        int x,y;
        For(i,1,m) {
            x=in(),y=in();
            ins(x,y+n,INF);
        }
        For(i,1,n) ins(0,i,1),ins(i+n,(n<<1|1),1);
    }
    void solve(){
        int ans=n;
        ans-=dinic(0,2*n+1);
        For(i,1,n)
            if (b[i]) continue;
            else{
                printf("%d",i);
                int k=i;
                while(to[k]){
                    k=to[k]-n;
                    printf(" %d",k);
                }
                printf("
    ");
            }
        printf("%d",ans);
    }
    int main(){
        read();
        solve();
    }

     本文由Melacau编写,Melacau代表M星向您问好,如果您不是在我的博客http://www.cnblogs.com/Melacau上看到本文,请您向我联系,email:13960948839@163.com.

  • 相关阅读:
    hadoop基础
    数据库基础知识
    sqoop基础
    大数据之常用linux常用命令
    zooKeeper基础
    impala基础
    Hbase基础
    Commitlint 提交规范类型
    理解JS闭包
    JS函数作用域及作用域链理解
  • 原文地址:https://www.cnblogs.com/Melacau/p/luogu2764.html
Copyright © 2020-2023  润新知