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

    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
    ",ans);
    	}
        return 0;
    }
    
    
  • 相关阅读:
    归并排序
    边割集
    NBUT 1225 NEW RDSP MODE I 2010辽宁省赛
    NBUT 1218 You are my brother 2010辽宁省赛
    NBUT 1220 SPY 2010辽宁省赛
    NBUT 1219 Time 2010辽宁省赛
    NBUT 1223 Friends number 2010辽宁省赛
    NBUT 1217 Dinner 2010辽宁省赛
    第七届蓝桥杯个人赛省赛--C语言B组
    2017广东工业大学程序设计竞赛决赛 tmk买礼物
  • 原文地址:https://www.cnblogs.com/PPXppx/p/11614109.html
Copyright © 2011-2022 走看看