zoukankan      html  css  js  c++  java
  • 洛谷 P1345 [USACO5.4]奶牛的电信Telecowmunication

    • 题意: 最小割
    • 思路: 点权为1,边权无限,要把点拆为出点和入点,由于指定了源点和汇点且源点汇点不能被割掉,超级源要连源点的出点,超级汇要连汇的入点。
    #include<bits/stdc++.h>
    #define ll long long
    using namespace std;
    typedef  pair<int,int> pii;
    const int N = 2000;
    const int INF = 0x3f3f3f3f;
    
    struct E{
        int u,v,flow,nxt;
        E(){}
        E(int u,int v,int flow,int nxt):u(u),v(v),flow(flow),nxt(nxt){}
    }e[N*2];
    
    int n,m,sp,tp,tot;
    int head[N],dis[N],pre[N],cur[N];
    void init(){
        tot = 0;    memset(head,-1,sizeof head);
    }
    void addE(int u,int v,int flow){
        e[tot].u = u; e[tot].v = v; e[tot].flow = flow; e[tot].nxt = head[u]; head[u] = tot++;
        e[tot].u = v; e[tot].v = u; e[tot].flow = 0; e[tot].nxt = head[v]; head[v] = tot++;
    }
    int q[N];
    int bfs(){
        int qtop = 0,qend=0;
        memset(dis,-1,sizeof dis);  
        dis[sp] = 0;    
        q[qend++] = sp;
        while(qtop!=qend){
            int u = q[qtop++];
            if(u==tp)   return true;
            for(int i=head[u];~i;i=e[i].nxt){
                int v = e[i].v;
                if(dis[v]==-1 && e[i].flow){
                    dis[v] = dis[u]+1;  
                    q[qend++] = v;
                }
            }
        }
        return dis[tp]!=-1;
    }
    int dfs(int u,int flow){
        int res = 0;
        if(u==tp)   return flow;
        for(int i=head[u];i!=-1&&flow;i=e[i].nxt){
            int v = e[i].v;
            if(dis[v]==dis[u]+1 && e[i].flow){
                int d = dfs(v,min(e[i].flow,flow));
                e[i].flow -=d;
                e[i^1].flow += d;
                res+=d;
                flow -= d;
            }
        }
        if(!res)
            dis[u] = -2;
        return res;
    }
    int dinic(){
        int ans=0;
        while(bfs()){
            ans+=dfs(sp,INF);
        }
        return ans;
    }
    int main(){
        int c1,c2;
        scanf("%d%d%d%d",&n,&m,&c1,&c2);
        sp = n*2 +1 , tp = sp +1;
        int u,v;
        init();
        addE(sp,c1+n,INF);
        addE(c2,tp,INF);
    
        for(int i=1;i<=n;++i)   addE(i,i+n,1);
        for(int i=1;i<=m;++i){
            scanf("%d%d",&u,&v);
            addE(u+n,v,INF);
            addE(v+n,u,INF);
        }
    
        printf("%d
    ",dinic());
        return 0;
    }
    
  • 相关阅读:
    图片不能显示
    Lambda表达式where过滤数据
    存储文本到一个文件里
    获取用户临时文件夹路径
    判断某一个字符串是否存在另一个字符串中
    使用反射为特性赋值
    字符串与数据流之间的转换
    控制台应用程序获取计算机名
    重复输出字符或字符串
    使用HashSet<>去除重复元素的集合
  • 原文地址:https://www.cnblogs.com/xxrlz/p/11620070.html
Copyright © 2011-2022 走看看