拆点+网络流

拆点建图应该是很常见的套路了。。一张无向图不联通,那么肯定有两个点不联通,但是我们不知道这两个点是什么。

所以我们枚举所有点,并把每个点拆成入点和出点,每次把枚举的两个点的入点作为s和t(这样方便,当然也可以把第一个点的出点当成s,第二个点的入点当成t,但其实我们把s和t的入点和出点之间的边容量设为INF之后就没有影响了)

每条原图的边连接着u的出点和v的入点,v的出点和u的入点,容量设为INF,保证不给割,其他点的入点和出点之间的容量当然是1。这样我们的割就一定会割在容量为1的边上,每割一条,就相当于去掉了一个点。暴力跑最大流早最小值就好了

#include <bits/stdc++.h>
#define INF 0x3f3f3f3f
#define full(a, b) memset(a, b, sizeof a)
using namespace std;
typedef long long ll;
inline int lowbit(int x){ return x & (-x); }
inline int read(){
int X = 0, w = 0; char ch = 0;
while(!isdigit(ch)) { w |= ch == '-'; ch = getchar(); }
while(isdigit(ch)) X = (X << 3) + (X << 1) + (ch ^ 48), ch = getchar();
return w ? -X : X;
}
inline int gcd(int a, int b){ return a % b ? gcd(b, a % b) : b; }
inline int lcm(int a, int b){ return a / gcd(a, b) * b; }
template<typename T>
inline T max(T x, T y, T z){ return max(max(x, y), z); }
template<typename T>
inline T min(T x, T y, T z){ return min(min(x, y), z); }
template<typename A, typename B, typename C>
inline A fpow(A x, B p, C lyd){
A ans = 1;
for(; p; p >>= 1, x = 1LL * x * x % lyd)if(p & 1)ans = 1LL * x * ans % lyd;
return ans;
}
const int N = 1000;
int n, m, cnt, head[N<<2], x[N<<2], y[N<<2], s, t, depth[N<<2], ans;
struct Edge { int v, next, f; } edge[N<<5]; void addEdge(int a, int b, int f){
edge[cnt].v = b, edge[cnt].f = f, edge[cnt].next = head[a], head[a] = cnt ++;
edge[cnt].v = a, edge[cnt].f = 0, edge[cnt].next = head[b], head[b] = cnt ++;
} bool bfs(){
full(depth, 0);
queue<int> q;
depth[s] = 1, q.push(s);
while(!q.empty()){
int cur = q.front(); q.pop();
//cout << cur << endl;
for(int i = head[cur]; i != -1; i = edge[i].next){
int u = edge[i].v;
if(!depth[u] && edge[i].f > 0){
depth[u] = depth[cur] + 1;
q.push(u);
}
}
}
return depth[t] != 0;
} int dfs(int cur, int a){
if(cur == t) return a;
int flow = 0;
for(int i = head[cur]; i != -1; i = edge[i].next){
int u = edge[i].v;
if(depth[u] == depth[cur] + 1 && edge[i].f > 0){
int k = dfs(u, min(a, edge[i].f));
a -= k, flow += k, edge[i].f -= k, edge[i^1].f += k;
}
if(!a) break;
}
if(a) depth[cur] = -1;
return flow;
} int dinic(){
int ret = 0;
while(bfs()) ret += dfs(s, INF);
return ret;
} void solve(){
full(head, -1), cnt = 0;
for(int i = 0; i < n; i ++){
if(i == s || i == t) addEdge(i, i + n, INF);
else addEdge(i, i + n, 1);
}
for(int i = 0; i < m; i ++){
addEdge(x[i] + n, y[i], INF), addEdge(y[i] + n, x[i], INF);
}
ans = min(ans, dinic());
} int main(){ while(scanf("%d%d", &n, &m) != EOF){
for(int i = 0; i < m; i ++){
int j; char str[100]; scanf("%s", str);
for(x[i] = 0, j = 1; str[j] != ','; j ++) x[i] = x[i] * 10 + (str[j] - '0');
for(y[i] = 0, j ++; str[j] != ')'; j ++) y[i] = y[i] * 10 + (str[j] - '0');
}
ans = INF;
for(int i = 0; i < n; i ++){
for(int j = i + 1; j < n; j ++){
s = i, t = j, solve();
}
}
if(n <= 1 || ans == INF) ans = 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 (无向图点连通度)

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

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

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

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

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

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

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

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

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

  9. POJ 1966 Cable TV Network (最大流最小割)

    $ POJ~1966~Cable~TV~Network $ $ solution: $ 第一眼可能让人很难下手,但本就是冲着网络流来的,所以我们直接一点.这道题我们要让这个联通图断开,那么势必会有两个 ...

随机推荐

  1. Win10 Anaconda下TensorFlow-GPU环境搭建详细教程(包含CUDA+cuDNN安装过程)

    目录 前言 第一步:安装Anaconda 1.下载和安装 2.配置Anaconda环境变量 第二步:安装TensorFlow-GPU 1.创建conda环境 2.激活环境 3.安装tensorflow ...

  2. virtualenv虚拟环境的使用

    前提条件:安装好python环境并配置好环境变量(可参考另一篇博文,python安装及配置) 1.打开cmd命令终端 pip3 install virtualenvwrapper-win(我电脑上面已 ...

  3. MySQL的常用命令:添加外键,修改字段名称,增加字段 设置主键自增长等

    Mysql命令添加外键 前提是有这么几个表  以mall_product 和 mall_category为例 ALTER TABLE mall_product ADD CONSTRAINT fore_ ...

  4. git出现: not a git repository

    使用用git add . 出现这样错误: fatal: not a git repository (or any of the parent directories): .git 意思是说:.git没 ...

  5. R语言绘制茎叶图

    与直方图相比,茎叶图更能细致的看出数据分布情况! 代码: > x<-c(25, 45, 50, 54, 55, 61, 64, 68, 72, 75, 75,+ 78, 79, 81, 8 ...

  6. Centos6.x升级内核方法支持Docker

    Centos6升级内核方法_百度经验https://jingyan.baidu.com/article/7e4409531bda252fc1e2ef4c.html

  7. Linux&Windows中VNC协议及使用方法

    [转载]window下使用vnc远程登录ubuntu/linux图形界面_五个粽子_新浪博客http://blog.sina.com.cn/s/blog_677265f601012mqg.html V ...

  8. syncthing 多主机同步文件工具

    周五看了下阮一峰的blog 看到有一个 syncthing的小工具挺好用的 进行了简单的尝试: 1. 下载文件位置: https://syncthing.net 2. 下载文件后的简单安装 绿色版直接 ...

  9. [转帖]nginx配置ssl加密(单/双向认证、部分https)

    nginx配置ssl加密(单/双向认证.部分https) https://segmentfault.com/a/1190000002866627   nginx下配置ssl本来是很简单的,无论是去认证 ...

  10. ResultHandler的用法

    ResultHandler,顾名思义,对返回的结果进行处理,最终得到自己想要的数据格式或类型.也就是说,可以自定义返回类型.下面通过一个例子讲解它的使用方法: 创建Goods实体类: public c ...