• ZOJ


    题意:判断最小割是否唯一.
    分析:跑出最大流后,在残余网上从源点和汇点分别dfs一次,对访问的点都打上标记.
    若还有点没有被访问到,说明最小割不唯一.

    https://www.cnblogs.com/ka200812/archive/2011/07/30/2121872.html 这里面的鬼畜图说的很清楚...

    #include<stdio.h>
    #include<iostream>
    #include<cstring>
    #include<queue>
    #include<algorithm>
    #include<vector>
    #include<cmath>
    using namespace std;
    const int INF = 0x3f3f3f3f;
    const int MAXN=2010;//点数的最大值
    const int MAXM=100010;//边数的最大值
    #define captype int
    
    struct SAP_MaxFlow{
        struct Edge{
            int from,to,next;
            captype cap;
        }edges[MAXM];
        int tot,head[MAXN];
        int gap[MAXN];
        int dis[MAXN];
        int cur[MAXN];
        int pre[MAXN];
    
        void init(){
            tot=0;
            memset(head,-1,sizeof(head));
        }
        void AddEdge(int u,int v,captype c,captype rc=0){
            edges[tot] = (Edge){u,v,head[u],c};  head[u]=tot++;
            edges[tot] = (Edge){v,u,head[v],rc}; head[v]=tot++;
        }
        captype maxFlow_sap(int sNode,int eNode, int n){//n是包括源点和汇点的总点个数,这个一定要注意
            memset(gap,0,sizeof(gap));
            memset(dis,0,sizeof(dis));
            memcpy(cur,head,sizeof(head));
            pre[sNode] = -1;
            gap[0]=n;
            captype ans=0;
            int u=sNode;
            while(dis[sNode]<n){
                if(u==eNode){
                    captype Min=INF ;
                    int inser;
                    for(int i=pre[u]; i!=-1; i=pre[edges[i^1].to])
                    if(Min>edges[i].cap){
                        Min=edges[i].cap;
                        inser=i;
                    }
                    for(int i=pre[u]; i!=-1; i=pre[edges[i^1].to]){
                        edges[i].cap-=Min;
                        edges[i^1].cap+=Min;
                    }
                    ans+=Min;
                    u=edges[inser^1].to;
                    continue;
                }
                bool flag = false;
                int v;
                for(int i=cur[u]; i!=-1; i=edges[i].next){
                    v=edges[i].to;
                    if(edges[i].cap>0 && dis[u]==dis[v]+1){
                        flag=true;
                        cur[u]=pre[v]=i;
                        break;
                    }
                }
                if(flag){
                    u=v;
                    continue;
                }
                int Mind= n;
                for(int i=head[u]; i!=-1; i=edges[i].next)
                if(edges[i].cap>0 && Mind>dis[edges[i].to]){
                    Mind=dis[edges[i].to];
                    cur[u]=i;
                }
                gap[dis[u]]--;
                if(gap[dis[u]]==0) return ans;
                dis[u]=Mind+1;
                gap[dis[u]]++;
                if(u!=sNode) u=edges[pre[u]^1].to;  //退一条边
            }
            return ans;
        }
    }F;
    
    
    
    int vis[MAXN];
    void dfs(int u)
    {
        vis[u] = 1;
        for(int i = F.head[u];~i;i=F.edges[i].next){
            int v = F.edges[i].to;
            if(!vis[v] && F.edges[i].cap>0)
                dfs(v);
        }
    }
    
    void rdfs(int u)
    {
        vis[u] = 2;
        for(int i = F.head[u];~i;i=F.edges[i].next){
            int v = F.edges[i].to;
            if(!vis[v] && F.edges[i^1].cap>0)
                rdfs(v);
        }
    }
    
    int main()
    {
        #ifndef ONLINE_JUDGE
            freopen("in.txt","r",stdin);
            freopen("out.txt","w",stdout);
        #endif
        int N,M,s,t,u,v,tmp;
        while(scanf("%d %d %d %d",&N, &M,&s,&t)==4){
            if(!N&&!M) break;
            F.init();
            for(int i=1;i<=M;++i){
                scanf("%d %d %d",&u, &v, &tmp);
                F.AddEdge(u,v,tmp);
                F.AddEdge(v,u,tmp);
            }
            memset(vis,0,sizeof(vis));
            F.maxFlow_sap(s,t,N+1);
            dfs(s);
            rdfs(t);
            bool flag = true;
            for(int i=1;i<=N;++i){
                if(!vis[i]){
                    flag = false;
                    break;
                }
            }
            if(flag) printf("UNIQUE
    ");
            else printf("AMBIGUOUS
    ");
        }
        return 0;
    }
    
    为了更好的明天
  • 相关阅读:
    win10 访问远程文件夹 此共享需要过时的SMB1协议 你不能访问此共享文件夹
    Navicat 1142 SELECT command denied to user 'sx'@'xxx' for table 'user'
    MySQL 密码参数配置与修改 validate_password
    MySQL 命令行下更好的显示查询结果
    MySQL 数据库的存储结构
    MySQL实验 内连接优化order by+limit 以及添加索引再次改进
    MySQL实验 子查询优化双参数limit
    MySQL 索引结构 hash 有序数组
    MySQL 树形索引结构 B树 B+树
    hbase2.1.9 centos7 完全分布式 搭建随记
  • 原文地址:https://www.cnblogs.com/xiuwenli/p/9686148.html
Copyright © 2020-2023  润新知