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;
    }
    
    
  • 相关阅读:
    在日本被禁止的コンプガチャ設計
    Starling常见问题解决办法
    Flixel引擎学习笔记
    SQLSERVER中修复状态为Suspect的数据库
    T4 (Text Template Transformation Toolkit)实现简单实体代码生成
    创建Linking Server in SQL SERVER 2008
    Linq to Sql 与Linq to Entities 生成的SQL Script与分页实现
    Linq to Entity 的T4 模板生成代码
    在VisualStudio2008 SP1中调试.net framework 源代码
    使用HttpModules实现Asp.net离线应用程序
  • 原文地址:https://www.cnblogs.com/PPXppx/p/11614109.html
Copyright © 2011-2022 走看看