zoukankan      html  css  js  c++  java
  • Smallest Minimum Cut HDU

    结论题,加边的时候每个边容量扩大为cap*(Edge+1)+1,跑一边最大流%(Edge+1)就是最少边数了

    证明一下就是一个容量为8的边和两个容量为4的边,扩大后只有堵住原先8才是最小的

    新最大流:maxflow*(Edge+1)+最少割边数

    #include<bits/stdc++.h>
    using namespace std;
    #define ll long long
    const int maxn=2e5+7;
    const int inf=0x3f3f3f3f;
    
    int num_nodes;
    int tot;
    int d[maxn],cur[maxn],source,sink;
    int p[maxn],num[maxn],vis[maxn];
    
    struct EDGE{
        int from,to,cap,flow;
    };
    vector<EDGE>edge;
    vector<int>G[maxn];
    
    void init(){
        edge.clear();
        for(int i=0;i<maxn;i++)G[i].clear();
    }
    
    void addedge(int u,int v,int w){
        edge.push_back((EDGE){u,v,w,0});
        edge.push_back((EDGE){v,u,0,0});
        tot=edge.size();
        G[u].push_back(tot-2);
        G[v].push_back(tot-1);
    }
    
    int bfs(){
        memset(vis,0,sizeof vis);
        queue<int>Q;
        Q.push(sink);
        vis[sink]=1;
        d[sink]=0;
        while(!Q.empty()){
            int u=Q.front();
            Q.pop();
            int sz=G[u].size();
            for(int i=0;i<sz;++i){
                EDGE &e=edge[G[u][i]^1];
                if(!vis[e.from] && e.cap>e.flow){
                    vis[e.from]=1;
                    d[e.from]=d[u]+1;
                    Q.push(e.from);
                }
            }
        }
        return vis[source];
    }
    
    int augment(){
        int u=sink,a=inf;
        while(u!=source){
            EDGE &e=edge[p[u]];
            a=min(a,e.cap-e.flow);
            u=edge[p[u]].from;
        }
        u=sink;
        while(u!=source){
            edge[p[u]].flow+=a;
            edge[p[u]^1].flow-=a;
            u=edge[p[u]].from;
        }
        return a;
    }
    
    int maxflow(){
        int flow=0;
        bfs();
        memset(num,0,sizeof num);
        for(int i=0;i<num_nodes;i++)num[d[i]]++;
        int u=source;
        memset(cur,0,sizeof cur);
        while(d[source]<num_nodes){
            if(u==sink){
                flow+=augment();
                u=source;
            }
            int advance=0;
            int sz=G[u].size();
            for(int i=cur[u];i<sz;i++){
                EDGE &e=edge[G[u][i]];
                if(e.cap>e.flow && d[u]==d[e.to]+1){
                    advance=1;
                    p[e.to]=G[u][i];
                    cur[u]=i;
                    u=e.to;
                    break;
                }
            }
            if(!advance){
                int m=num_nodes-1;
                int sz=G[u].size();
                for(int i=0;i<sz;i++){
                    if(edge[G[u][i]].cap>edge[G[u][i]].flow){
                        m=min(m,d[edge[G[u][i]].to]);
                    }            
                }
                if(--num[d[u]]==0)break;
                num[d[u]=m+1]++;
                cur[u]=0;
                if(u!=source)u=edge[p[u]].from;
            }
        }
        return flow;
    }
    
    int main(){
        int T;scanf("%d",&T);
        while(T--){
            init();
            int n,m;scanf("%d%d",&n,&m);
            num_nodes=n+10;
            scanf("%d%d",&source,&sink);
            for(int i=1,u,v,w;i<=m;i++){
                scanf("%d%d%d",&u,&v,&w);
                addedge(u,v,w*(m+1)+1);//addedge(v,u,w*(m+1)+1);
            }
            printf("%d
    ",maxflow()%(m+1));
        }
    }



  • 相关阅读:
    Java之正則表達式【使用语法】
    2015年创业中遇到的技术问题:71-80
    2015年创业中遇到的技术问题:71-80
    Kinect小小玩偶游戏----小小潜水员
    微信开发学习日记(三):6点经验
    微信开发学习日记(二):3个案例
    2015年创业中遇到的技术问题:61-70
    2015年创业中遇到的技术问题:61-70
    2次创业经验谈(想创业想做事的人不要错过)
    Kinect舒适区范围--UE4 的Blueprint测试范例
  • 原文地址:https://www.cnblogs.com/Drenight/p/8611253.html
Copyright © 2011-2022 走看看