$ POJ1966CableTVNetwork $



$ solution: $

第一眼可能让人很难下手,但本就是冲着网络流来的,所以我们直接一点。这道题我们要让这个联通图断开,那么势必会有两个点变得不连通,这道题的数据范围很小,所以我们试着暴力枚举两个点。这样就变成了最小割。不过,嗯?割的东西怎么是点?

为了靠近我们已经学得知识,我们想办法看,能不能割点变成割边。反正网络流最喜欢千变万化、左右建模了。。。于是我们引进书上的一个东西:

  1. 一个节点可以拆成两个节点,将原节点用中间那条边表示
  2. 一条边可以拆成两条边,将原边用中间那个点表示
  3. 中间的边权为1代表这个点是否被割,旁边的边权为inf是为了排除其影响(因为它不可能被割掉)

我们用第一条和第三条性质可以解决这个问题。首先对于每个节点建立两个 $ i $ 和 $ i+n $ 节点。然后这两个节点之间用一条权值为1的有向边(从 $ i $ 到 $ i+n $ ) ,如果这条边在最小割中被割掉(等价于原本的点被割掉)。然后 $ i $ 节点连入边(权值正无穷), $ i+n $ 节点连出边(权值正无穷),连正无穷是为了让割掉的边只能是中间的边。然后我们跑一遍最大流,它对应的最小割里每条代表原来一个点,因为权值为1,所以流量就是答案。

注意:我们的源汇点也要被分为两个点,而网络流中的实际源点是 $ S+n $ ,它连出边。因为源汇点的性质,这两个点不可能被割掉,所以它们中间不连边。



$ code: $

#include<iostream>
#include<cstdio>
#include<iomanip>
#include<algorithm>
#include<cstring>
#include<cstdlib>
#include<ctime>
#include<cmath>
#include<vector>
#include<queue>
#include<map>
#include<set> #define ll long long
#define db double
#define rg register int using namespace std; int n,m,S,T;
int ans,top=1;
int dep[505];
int tou[505];
int qi[505];
int f[55][55]; struct su{
int to,v,next;
}b[5005]; inline int qr(){
register char ch; register bool sign=0; rg res=0;
while(!isdigit(ch=getchar()))if(ch=='-')sign=1;
while(isdigit(ch))res=res*10+(ch^48),ch=getchar();
if(sign)return -res; else return res;
} inline void add(int x,int y,int v){ //注意博主加边自带反向
b[++top]=su{y,v,tou[x]}; tou[x]=top;
b[++top]=su{x,0,tou[y]}; tou[y]=top;
} inline bool bfs(int x){
for(rg i=1;i<=x;++i)
qi[i]=tou[i],dep[i]=0;
queue<int> q; q.push(S); dep[S]=1;
while(!q.empty()){
rg i=q.front(); q.pop();
for(rg j=tou[i];j;j=b[j].next)
if(b[j].v&&!dep[b[j].to]){
dep[b[j].to]=dep[i]+1;
if(b[j].to==T)return 1;
q.push(b[j].to);
}
} return 0;
} inline int dfs(int i,int w){
if(i==T||!w)return w;
rg rest=w,f;
for(rg &j=qi[i];j;j=b[j].next){
if(b[j].v&&dep[b[j].to]==dep[i]+1){
f=dfs(b[j].to,min(w,b[j].v));
if(!f){dep[b[j].to]=-2; continue;}
b[j].v-=f; b[j^1].v+=f; w-=f;
} if(!w)break;
}return rest-w;
} inline void solve(){
rg res=0; top=1;
for(rg i=1;i<=n*2+2;++i) tou[i]=0; //初始化
for(rg i=1;i<=n;++i){
if(i!=S&&i!=T)add(i,i+n,1); //一点拆成两点,中间连边
for(rg j=1;j<=n;++j)
if(f[i][j])add(i+n,j,1e9); //连边注意是否有加n操作
} S=S+n;
while(bfs(n*2+2)) res+=dfs(S,1e9); //DInic
ans=min(res,ans);
} int main(){
//freopen(".in","r",stdin);
//freopen(".out","w",stdout);
rg t=qr();
while(t--){
n=qr();m=qr();
for(rg i=1;i<=n;++i){
for(rg j=i;j<=n;++j){
f[i][j]=f[j][i]=0; //初始化
}
}
for(rg i=1;i<=m;++i){
rg x=qr()+1,y=qr()+1;
f[x][y]=f[y][x]=1; //邻接矩阵读边
}
if(n==0||n==2){puts("0");continue;}
if(m==0&&n&&n!=2){puts("1");continue;}//特判,这题有点卡细节
ans=1e9;
for(rg i=1;i<=n;++i){
for(rg j=1;j<=n;++j){
if(f[i][j]||i==j)continue; //注意两个相邻的点不可能通过割点不联通
S=i;T=j; solve(); //枚举源汇点
}
} if(ans==1e9)ans=n; //无论怎么割点图都联通,就输出n
printf("%d\n",ans);
}
return 0;
}

POJ 1966 Cable TV Network (最大流最小割)的更多相关文章

  1. POJ 1966 Cable TV Network

    Cable TV Network Time Limit: 1000MS   Memory Limit: 30000K Total Submissions: 4702   Accepted: 2173 ...

  2. POJ 1966 Cable TV Network(顶点连通度的求解)

                               Cable TV Network Time Limit: 1000MS   Memory Limit: 30000K Total Submissi ...

  3. POJ 1966 Cable TV NETWORK(网络流-最小点割集)

                                    Cable TV NETWORK The interconnection of the relays in a cable TV net ...

  4. POJ 1966 Cable TV Network 【经典最小割问题】

    Description n个点的无向图,问最少删掉几个点,使得图不连通 n<=50 m也许可以到完全图? Solution 最少,割点,不连通,可以想到最小割. 发现,图不连通,必然存在两个点不 ...

  5. POJ 1966 Cable TV Network (点连通度)【最小割】

    <题目链接> 题目大意: 给定一个无向图,求点连通度,即最少去掉多少个点使得图不连通. 解题分析: 解决点连通度和边连通度的一类方法总结见   >>> 本题是求点连通度, ...

  6. POJ 1966 Cable TV Network (无向图点连通度)

    [题意]给出一个由n个点,m条边组成的无向图.求最少去掉多少点才能使得图中存在两点,它们之间不连通. [思路]回想一下s->t的最小点割,就是去掉多少个点能使得s.t不连通.那么求点连通度就枚举 ...

  7. POJ 1966 Cable TV Network (算竞进阶习题)

    拆点+网络流 拆点建图应该是很常见的套路了..一张无向图不联通,那么肯定有两个点不联通,但是我们不知道这两个点是什么. 所以我们枚举所有点,并把每个点拆成入点和出点,每次把枚举的两个点的入点作为s和t ...

  8. poj 1966 Cable TV Network 顶点连通度

    题目链接 给一个图, n个点m条边, 求至少去掉多少个点可以使得图不再联通.随便指定一个点为源点, 枚举其他点为汇点的情况, 跑网络流, 求其中最小的情况. 如果最后ans为inf, 说明是一个完全图 ...

  9. POJ - 1966 Cable TV Network (最大流求点连通度)

    题意:求一个无向图的点连通度.点联通度是指,一张图最少删掉几个点使该图不连通:若本身是非连通图,则点连通度为0. 分析:无向图的点连通度可以转化为最大流解决.方法是:1.任意选择一个点作为源点:2.枚 ...

随机推荐

  1. spring boot官方配置

    #BANNER banner.charset = UTF-8 #横幅文件编码.banner.location = classpath:banner.txt #横幅文件位置.banner.image.l ...

  2. Python学习之==>第三方模块的安装、模块导入

    一.模块&包 1.模块 模块实质上就是一个Python文件,它是用来组织代码的.意思就是把Python代码写在里面,文件名就是模块的名称.例如:random.py,random就是模块的名称. ...

  3. Java面试题集(131-135)

    Java程序员面试题集(131-135) 摘要:这部分内容准备重新发布为Java程序员面试题集(151-180),但这篇帖子仍然保留在这里.查看新内容请点击Java程序员面试题集(151-180) 1 ...

  4. html的标签规范

    if/else标签{ % if condition1 %} ... display 1{ % elif conditon2 %} ... display 2{ % else % } ... displ ...

  5. CNN(卷积神经网络)原理讲解及简单代码

    一.原理讲解 1. 卷积神经网络的应用 分类(分类预测) 检索(检索出该物体的类别) 检测(检测出图像中的物体,并标注) 分割(将图像分割出来) 人脸识别 图像生成(生成不同状态的图像) 自动驾驶 等 ...

  6. eclipse sts 常规操作

    项目:右键 refresh 右键 maven -> update project 重新remove add project    重启软件,电脑 1.项目冗余 Package Explorer ...

  7. 书籍:wpf学习书籍介绍

    WPF参考书推荐 下面先整理下,本人主要学习的WPF参考书: 1.WPF编程宝典(C#2010) 该书:(必读) 心得体会:读完该书后,你对WPF的基础和基本控件的使用,包括WPF的编程模型,相比Wi ...

  8. [转帖]100G QSFP28与CFP,CFP2,CFP4光模块的比较

    100G QSFP28与CFP,CFP2,CFP4光模块的比较 https://www.eefocus.com/etulink/blog/17-09/423967_5c520.html 数据中心网络发 ...

  9. [19/09/18-星期三] Python中的序列

    一. # 第四章 序列(视频58-76) ## 列表(list) - 列表是Python中的一个对象 - 对象(object)就是内存中专门用来存储数据的一块区域 - 之前我们学习的对象,像数值,它只 ...

  10. RabbitMq学习6-安装php-amqplib(RabbitMQ的phpAPI)

    一.使用composer安装php-amqplib 1.在你的项目中添加一个 composer.json文件: { "require": { "php-amqplib/p ...