• UVA1660 电视网络 Cable TV Network[拆点+最小割]


    题意翻译

    题目大意: 给定一个n(n <= 50)个点的无向图,求它的点联通度。即最少删除多少个点,使得图不连通。

    解析

    网络瘤拆点最小割。

    定理

    最大流(=)最小割

    感性地理解(口胡)一下:首先显然最大流(<=)割,而根据最大流定义,最小割恰恰就是要恰好割断最大流经过的所有最窄流量的边集,就能恰好使得源点和汇点不连通,即最大流(=)最小割。

    至于具体的证明,我也不知道


    拆点

    一般来说,正常的拆点有两个作用:

    1. 在不改变原图连通性的情况下,将点权转化为边权。
    2. 通过化点为边,限制通过某点的流量。

    对于无向图和有向图,一般意义上的拆点做法是相同的。


    一般做法:以有向图为例,对于原图中的一个点对((x,y)),且有一条有向边(c(x,y))。我们将其分别拆成两个点(x,x',y,y'),然后(x ightarrow x',y ightarrow y')这样连接有向边,如果原来的点有点权那么将有向边的边权赋值为点权,如果没有点权则赋值为1。对于原图存在的有向边,连接(x' ightarrow y)

    对于无向边,我们再连一条边(y' ightarrow x)即可。


    那么对于本题,显然是一个求最少割点,我们转化为拆点最大流做。

    注意可能有多组数据。

    参考代码

    #include<cstdio>
    #include<iostream>
    #include<cmath>
    #include<cstring>
    #include<ctime>
    #include<cstdlib>
    #include<algorithm>
    #include<queue>
    #include<set>
    #include<map>
    #define INF 0x3f3f3f3f
    #define N 110
    using namespace std;
    struct node{
    	int next,ver,leng;
    }g[N<<1];
    int tot,head[N],d[N],n,m,a[N],b[N],s,t;
    inline void add(int x,int y,int val)
    {
    	g[++tot].ver=y,g[tot].leng=val;
    	g[tot].next=head[x],head[x]=tot;
    }
    inline bool bfs()
    {
    	memset(d,0,sizeof(d));
    	queue<int> q;
    	d[s]=1;q.push(s);
    	while(q.size()){
    		int x=q.front();q.pop();
    		for(int i=head[x];i;i=g[i].next){
    			int y=g[i].ver,z=g[i].leng;
    			if(!z||d[y]) continue;
    			d[y]=d[x]+1;
    			if(y==t) return 1;
    			q.push(y);
    		}
    	}
    	return 0;
    }
    inline int dinic(int x,int flow)
    {
    	if(x==t) return flow;
    	int rest=flow;
    	for(int i=head[x];i&&rest;i=g[i].next){
    		int y=g[i].ver,z=g[i].leng;
    		if(!z||d[y]!=d[x]+1) continue;
    		int k=dinic(y,min(rest,z));
    		if(!k) d[y]=0;
    		else{
    			g[i].leng-=k;
    			g[i^1].leng+=k;
    			rest-=k;
    		}
    	}
    	return flow-rest;
    }
    int main()
    {
    	while(~scanf("%d%d",&n,&m)){
    		int ans=INF;
    		for(int i=0;i<m;++i){
    			a[i]=b[i]=0;
    			char str[20];
    			scanf("%s",str);
    			int j=1;
    			while(str[j]!=',') a[i]=a[i]*10+str[j]-'0',++j;
    			j++;
    			while(str[j]!=')') b[i]=b[i]*10+str[j]-'0',++j; 
    		}
    		for(s=0;s<n;++s)
    			for(t=0;t<n;++t){
    				if(s==t) continue;
    				memset(head,0,sizeof(head));
    				tot=1;
    				for(int i=0;i<n;++i)
    					if(i==s||i==t) add(i,i+n,INF),add(i+n,i,0);
    					else add(i,i+n,1),add(i+n,i,0);
    				for(int i=0;i<m;++i){
    					add(a[i]+n,b[i],INF),add(b[i]+n,a[i],INF);
    					add(b[i],a[i]+n,0),add(b[i],a[i]+n,0);
    				}
    				int now=0,tmp=0;
    				while(bfs())
    					while((now=dinic(s,INF))) tmp+=now; 
    				ans=min(ans,tmp);
    			}
    		if(n<=1||ans==INF) ans=n;
    		cout<<ans<<endl;
    	}
    	return 0;
    }
    
  • 相关阅读:
    吴恩达机器学习笔记 —— 3 线性回归回顾
    springboot整合pagehelper实现分页
    Spring 线程池实战
    Java web后台插入数据库中文乱码问题解决
    Cesium项目实战(5)-城市各类POI数据制作、加工、展示
    Cesium项目实战(2)-城市行政区划信息展示以及专题信息展示
    【mybatis】mybatis中避免where空条件后面添加1=1垃圾条件的 优化方法
    Java之Json转List实体
    Maven项目META-INF文件夹不存在的问题
    Maven打jar包把配置文件放在META-INF目录下
  • 原文地址:https://www.cnblogs.com/DarkValkyrie/p/11376443.html
Copyright © 2020-2023  润新知