ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

Cable TV Network

2019-09-30 20:59:59  阅读:287  来源: 互联网

标签:ch 删点 Network Cable TV int while incf include


POJ

洛咕-UVA

洛咕-SP(输入格式稍微不同)

题意:给定一张无向图,\(n\)个点\(m\)条边,求最少去掉多少个点,可以使图不连通.\(n<=50\).

分析:图不连通等价于图中必定有两个点不连通,数据范围又这么小,所以我们直接枚举\(S,T\)两个点不连通,取最小值就是答案了.

构建网络流最小割模型(因为最小割是边集,而本题是要删点,所以我们要考虑把删点转化成删边):拆点法.把原来的每个点\(x\)拆成\(x,x+n\),对于图中非\(S,T\)点,连有向边\((x,x+n,1)\)(删点\(x\)等价于删这条边了);题目给出的无向边连有向边\((x+n,y,1e9),(y+n,x,1e9)\)(因为题目中只能删点,不能删边,所以容量设为无穷大,不会被选入最小割,即不会被删掉.)

源点\(s+n\),汇点\(t\),跑最大流模板即可.

#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
#include<cmath>
#include<queue>
#include<map>
#include<set>
#define ll long long
using namespace std;
inline int read(){
    int x=0,o=1;char ch=getchar();
    while(ch!='-'&&(ch<'0'||ch>'9'))ch=getchar();
    if(ch=='-')o=-1,ch=getchar();
    while(ch>='0'&&ch<='9')x=x*10+ch-'0',ch=getchar();
    return x*o;
}
const int N=100005;//懒得计算数组具体要开多大了
int n,m,s,t,max_flow,ans;
int a[N],b[N],visit[105],incf[105],pre[105],bj[55][55];
int tot,head[105],nxt[N],to[N],w[N];
inline void add(int a,int b,int c){
    nxt[++tot]=head[a];head[a]=tot;to[tot]=b;w[tot]=c;
    nxt[++tot]=head[b];head[b]=tot;to[tot]=a;w[tot]=0;
}//网络流的"有向边"不是最短路中的有向边
inline bool bfs(){//模板
    memset(visit,0,sizeof(visit));;
    queue<int>q;q.push(s+n);
    visit[s+n]=1;incf[s+n]=1e9;
    while(q.size()){
        int u=q.front();q.pop();
        for(int i=head[u];i;i=nxt[i]){
            if(!w[i])continue;
            int v=to[i];if(visit[v])continue;
            incf[v]=min(incf[u],w[i]);
            pre[v]=i;q.push(v);visit[v]=1;
            if(v==t)return 1;
        }
    }
    return 0;
}
inline void update(){//模板
    int x=t;
    while(x!=s+n){
        int i=pre[x];
        w[i]-=incf[t];
        w[i^1]+=incf[t];
        x=to[i^1];
    }
    max_flow+=incf[t];
}
int main(){
    while(scanf("%d%d",&n,&m)!=EOF){
        if(!m){//可以直接特判m=0的情况
            if(n==1)puts("1");
            else puts("0");
            continue;
        }
        memset(bj,0,sizeof(bj));
        for(int i=1;i<=m;++i){
            a[i]=read()+1,b[i]=read()+1;
            bj[a[i]][b[i]]=bj[b[i]][a[i]]=1;
        }
        ans=1e9;//刚开始没初始化这个,挂了好久
        for(s=1;s<n;++s){//枚举源点
            for(t=s+1;t<=n;++t){//枚举汇点
                if(t==s||bj[s][t])continue;//如果s,t直接相连,不可能达到要求
                tot=1;for(int i=0;i<=101;++i)head[i]=0;//建图初始化
                for(int i=1;i<=n;++i){
                    if(i==s||i==t)add(i,i+n,1e9);
                    else add(i,i+n,1);
                }
                for(int i=1;i<=m;++i){
                    add(a[i]+n,b[i],1e9);
                    add(b[i]+n,a[i],1e9);
                }
                max_flow=0;
                while(bfs())update();
                ans=min(ans,max_flow);
            }
        }
        if(ans==1e9)ans=n;
        printf("%d\n",ans);
    }
    return 0;
}

标签:ch,删点,Network,Cable,TV,int,while,incf,include
来源: https://www.cnblogs.com/PPXppx/p/11614109.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有