zoukankan      html  css  js  c++  java
  • UVA 10480 Sabotage (最大流最小割)

    题目链接:点击打开链接

    题意:把一个图分成两部分,要把点1和点2分开。隔断每条边都有一个花费,求最小花费的情况下,应该切断那些边。
    这题很明显是最小割,也就是最大流。把1当成源点,2当成汇点。
    问题是要求最小割应该隔断那条边。

    思路:求最小割就是求最大流,求完后,剩余网络中,能由起点到达的是和起点一个集合的,其他的都是和终点一个集合的。

    #include<iostream>
    #include<stdio.h>
    #include<stdlib.h>
    #include<string.h>
    #include<math.h>
    #include<vector>
    #include<queue>
    #include<map>
    #include<set>
    #include<string>
    #include<bitset>
    #include<algorithm>
    using namespace std;
    #define lson th<<1
    #define rson th<<1|1
    typedef long long ll;
    typedef long double ldb;
    #define inf 99999999
    #define pi acos(-1.0)
    #define Key_value ch[ch[root][1]][0]
    
    #define maxn 400  //最大点的个数
    #define maxm 400005 //最大边的个数
    #define INF 1<<30
    int gra[60][60];
    struct Edge
    {
        int to,next,cap,flow,from;
        Edge(){}
        Edge(int from,int to,int next,int cap,int flow):from(from),to(to),next(next),cap(cap),flow(flow){}
    }edge[maxm];
    int vs,vt,VN;
    int tot;
    int first[maxn];
    int gap[maxn],dep[maxn],cur[maxn];
    void addedge(int u,int v,int w)
    {
        edge[tot]=Edge(u,v,first[u],w,0);
        first[u]=tot++;
    
        edge[tot]=Edge(v,u,first[v],0,0);
        first[v]=tot++;
    }
    int q[maxn];
    void bfs(int vt)
    {
        memset(dep,-1,sizeof(dep));
        memset(gap,0,sizeof(gap));
        gap[0]=1;
        int front=0,rear=0;
        dep[vt]=0;
        q[rear++]=vt;
        while(front!=rear){
            int u=q[front++];
            for(int i=first[u];i!=-1;i=edge[i].next){
                int v=edge[i].to;
                if(dep[v]!=-1)continue;
                q[rear++]=v;
                dep[v]=dep[u]+1;
                gap[dep[v]]++;
            }
        }
    }
    int S[maxn];
    int sap(int vs,int vt,int VN) //VN表示总的点数,vs表示起点,vt表示终点
    {
        bfs(vt);
        memcpy(cur,first,sizeof(first));
        int top=0,u=vs,ans=0;
        while(dep[vs]<VN){
            if(u==vt){
                int Min=INF,inser;
                for(int i=0;i<top;i++){
                    if(Min>edge[S[i]].cap-edge[S[i] ].flow){
                        Min=edge[S[i]].cap-edge[S[i] ].flow;
                        inser=i;
                    }
                }
                for(int i=0;i<top;i++){
                    edge[S[i]].flow+=Min;
                    edge[S[i]^1].flow-=Min;
                    //edge[S[i]].cap-=Min;
                    //edge[S[i]^1].cap+=Min;
                }
                ans+=Min;
                top=inser;
                u=edge[S[top]^1].to;
                continue;
            }
            bool flag=false;
            int v;
            for(int i=cur[u];i!=-1;i=edge[i].next){
                v=edge[i].to;
                if(edge[i].cap-edge[i].flow && dep[v]+1==dep[u]){
                    flag=true;cur[u]=i;break;
                }
            }
            if(flag){
                S[top++]=cur[u];u=v;continue;
            }
            int Min=VN;
            for(int i=first[u];i!=-1;i=edge[i].next){
                if(edge[i].cap-edge[i].flow && dep[edge[i].to]<Min){
                    Min=dep[edge[i].to];
                    cur[u]=i;
                }
            }
            gap[dep[u]]--;
            if(!gap[dep[u]])return ans;
            dep[u]=Min+1;
            gap[dep[u]]++;
            if(u!=vs)u=edge[S[--top]^1].to;
        }
        return ans;
    }
    int vis[100];
    
    void bfs( )
    {
        int front,rear;
        front=1;rear=1;
        q[rear]=vs;
        int x,v,i;
        while(front<=rear){
            x=q[front];
            front++;
            for(i=first[x];i!=-1;i=edge[i].next){
                v=edge[i].to;
                if(vis[v])continue;
                if(edge[i].cap && edge[i].cap>edge[i].flow){
                    rear++;
                    q[rear]=v;
                    vis[v]=1;
                }
    
            }
    
    
        }
    }
    
    int main()
    {
        int n,m,i,j,c,d,f,u,v;
        while(scanf("%d%d",&n,&m)!=EOF)
        {
            if(n==0 && m==0)break;
            tot=0;
            memset(first,-1,sizeof(first));
            VN=n,vs=1,vt=2;
    
            for(i=1;i<=m;i++){
                scanf("%d%d%d",&c,&d,&f);
                addedge(c,d,f);
                addedge(d,c,f);
            }
            sap(vs,vt,VN);
            /*
            printf("
    
    ");
            for(i=0;i<=tot;i++){
                printf("%d %d %d %d
    ",edge[i].from,edge[i].to,edge[i].cap,edge[i].flow);
            }
            */
    
            /*
            for(u=1;u<=n;u++){
                for(i=first[u];i!=-1;i=edge[i].next){
                    v=edge[i].to;
                    if(edge[i].cap && edge[i].flow && edge[i].flow==edge[i].cap){
                        printf("%d %d
    ",u,v);
                    }
                }
            }
            */
            memset(vis,0,sizeof(vis));
            vis[vs]=1;
            bfs();
    
            /*
            for(i=1;i<=n;i++){
                printf("--->%d %d
    ",i,vis[i]);
            }
            */
    
            memset(gra,0,sizeof(gra));  //gra保存的是答案
            for(i=1;i<=tot;i++){
                int u=edge[i].from;
                int v=edge[i].to;
                if(u>v)swap(u,v);
                if((vis[u] && !vis[v]) || (!vis[u] && vis[v] ) ){
                    gra[u][v]=gra[v][u]=1;
                }
    
            }
            for(i=1;i<=n;i++){
                for(j=i+1;j<=n;j++){
                    if(gra[i][j]){
                        printf("%d %d
    ",i,j);
                    }
                }
            }
            printf("
    ");
        }
        return 0;
    }
    
    /*
    3 2
    1 3 20
    3 2 10
    
    */
    


  • 相关阅读:
    vmware12中安装MAC OS X 10.10
    AOL search
    [python]错误检测及异常处理try-except
    [推荐]
    [python]打开文件操作open用法
    MAC使用小技巧
    [推荐]
    [python]python中的if, while, for
    [python]python字典
    [python]python列表、元组
  • 原文地址:https://www.cnblogs.com/herumw/p/9464479.html
Copyright © 2011-2022 走看看