zoukankan      html  css  js  c++  java
  • POJ 1966 Cable TV Network

    题目链接: POJ 1966 Cable TV Network

    题目大意:

    一张 (N) 个点的无向图,求最少删去多少点后可以使得图不连通。

    (0leq Nleq 50)

    思路:

    这里有一个小技巧:点转边

    将每个点拆成一个出点和一个入点,入点连接所有进边,出点连接所有出边,两点间连一条权值为 (1) 的边,代表删除这个点的代价,而连在原先点与点之间的边权值设为 (infty),防止删除了真正的边。

    然后这题就转化成最小割了,枚举源点 (S) 和汇点 (T) ,将最小割更新答案即可。

    细节:

    挺板子的,就是 (S)(T) 不能是同一个点即可, (S) 是该点的出点, (T) 是另外那个点的入点。

    Code:

    #include<iostream>
    #include<cstdio>
    #include<cstring>
    #include<queue>
    #include<fstream>
    #define mem(a,b) memset(a,b,sizeof(a))
    #define rep(i,a,b) for(int i=a;i<=b;i++)
    #define per(i,b,a) for(int i=b;i>=a;i--)
    #define N 105
    #define M 5200
    #define Inf 0x3f3f3f3f
    using namespace std;
    inline int read(){
        int s=0,w=1;
        char ch=getchar();
        while(ch<'0'||ch>'9'){if(ch=='-')w=-1;ch=getchar();}
        while(ch>='0'&&ch<='9')s=(s<<3)+(s<<1)+(ch^48),ch=getchar();
        return s*w;
    }
    int head[N],to[M],nxt[M];
    int cnt,s,t;
    int val[M],cap[M],d[N];
    bool conn[N][N];
    queue<int> q;
    void init(){mem(head,-1),cnt=-1,mem(conn,false);}
    void add_e(int a,int b,int w){
        nxt[++cnt]=head[a],head[a]=cnt,to[cnt]=b;
        val[cnt]=cap[cnt]=w;
        if(w)add_e(b,a,0);
    }
    bool bfs(){
        mem(d,0);
        while(!q.empty())q.pop();
        d[s]=1,q.push(s);
        while(!q.empty()){
            int cur=q.front(); q.pop();
            for(int i=head[cur];~i;i=nxt[i]){
                if(cap[i]&&!d[to[i]]){
                    d[to[i]]=d[cur]+1;
                    q.push(to[i]);
                    if(to[i]==t)return true;
                }
            }
        }
        return false;
    }
    int dinic(int x,int flow){
        if(x==t)return flow;
        int rest=flow,k;
        for(int i=head[x];(~i)&&rest;i=nxt[i]){
            if(cap[i]&&d[to[i]]==d[x]+1){
                k=dinic(to[i],min(cap[i],rest));
                if(!k)d[to[i]]=0;
                cap[i]-=k,cap[i^1]+=k;
                rest-=k;
            }
        }
        return flow-rest;
    }
    int main(){
        int n,m,a,b;
        while(cin>>n>>m){
            if(n==1){
                cout<<"1
    ";
                continue;
            }
            init();
            rep(i,1,m){
                a=read(),b=read(),conn[a][b]=true;
                add_e(a+n,b,Inf),add_e(b+n,a,Inf);
            }
            rep(i,0,n-1)add_e(i,i+n,1);
            int ans=n;
            rep(i,0,n-1)rep(j,0,n-1){
                if(conn[i][j]||i==j)continue;
                rep(k,0,cnt)cap[k]=val[k];
                s=i+n,t=j;
                int maxflow=0,flow;
                while(bfs()){
                    while(flow=dinic(s,Inf))maxflow+=flow;
                }
                ans=min(ans,maxflow);
            }
            cout<<ans<<endl;
        }
        return 0;
    }
    
  • 相关阅读:
    docker容器打包、镜像文件导入与导出 , 支持批量
    服务器高并发配置优化
    php集成财付通支付接口
    C# 防界面假死
    以二进制方式读取图片保存到string
    转载 C#开发串口总结,并提炼串口辅助类到公用类库中
    C# comport 打印图像
    C#实现MD5加密
    execute sp_executesql 用变量获取返回值
    C# 获取计算机cpu 硬盘 网卡信息
  • 原文地址:https://www.cnblogs.com/Neal-lee/p/14397868.html
Copyright © 2011-2022 走看看