题目描述

农夫约翰的奶牛们喜欢通过电邮保持联系,于是她们建立了一个奶牛电脑网络,以便互相交流。这些机器用如下的方式发送电邮:如果存在一个由c台电脑组成的序列a1,a2,…,a©,且a1与a2相连,a2与a3相连,等等,那么电脑a1和a©就可以互发电邮。

很不幸,有时候奶牛会不小心踩到电脑上,农夫约翰的车也可能碾过电脑,这台倒霉的电脑就会坏掉。这意味着这台电脑不能再发送电邮了,于是与这台电脑相关的连接也就不可用了。

有两头奶牛就想:如果我们两个不能互发电邮,至少需要坏掉多少台电脑呢?请编写一个程序为她们计算这个最小值。

以如下网络为例:

1* / 3 - 2*

这张图画的是有2条连接的3台电脑。我们想要在电脑1和2之间传送信息。电脑1与3、2与3直接连通。如果电脑3坏了,电脑1与2便不能互发信息了。

输入格式 第一行

四个由空格分隔的整数:N,M,c1,c2.N是电脑总数(1<=N<=100),电脑由1到N编号。M是电脑之间连接的总数(1<=M<=600)。最后的两个整数c1和c2是上述两头奶牛使用的电脑编号。连接没有重复且均为双向的(即如果c1与c2相连,那么c2与c1也相连)。两台电脑之间至多有一条连接。电脑c1和c2不会直接相连。

第2到M+1行 接下来的M行中,每行包含两台直接相连的电脑的编号。

输出格式 一个整数表示使电脑c1和c2不能互相通信需要坏掉的电脑数目的最小值。

输入输出样例

输入 #1 复制
3 2 1 2
1 3
2 3
输出 #1 复制
1

思路

题意:这一题是问cow需要最少破话多少台电脑才能 才能使位于起点和终点位置的 cow 不能通信,也就是说这一题是让拆的是,而不是让拆的边,我们不能够直接使用,这一题如果是让拆的是边的话,那就很简单,因为不能够通信,就意味着 在拆边之后,图的联通性就没了,图被分割成两部分,那么我们所要求的是最小割。。。。。这一题是 割点 ,当我们在破坏掉一个u 之后(假设这一条边为 u——v),我们不能够影响原来 v点的通与其他点的通信(除了u点),这一题如果我们能够把个 割点——> 转化割边 就好解决了

思路:我们可以考虑把 一个点(假定编号为 i)拆成两个点,这两个点的编号是 :i , i + n,在 i 与 i+1 点之间有一条权值为 1 指向 i+1 点的边(i+1这个点 和这个边是我们要用 Add函数添加进去的) ,还有一点要明白,对于题上给的边,所有与原来 i 所连的点 进入i的边 还是i ,而原来 从 i 点出去的边要变成 从 i + 1 点过出去的边,一定是可以双向通行,而且可以无线通信(所以题目上给的边就是 INF),i 点拆分后的结果



当我们把所有的点之后,再把 题目上给的边我们就得到了最终的图:



上图⬆️中 的 红线:拆点之间的边权为 1 的线,黑线是题目给的边权值为 INF

最后最后:我么要特殊考虑:源点s 与汇点e , 我们要明白 原点可以通过与 源点相连的边无限发送消息,而不是一次,所以我们 这个时候 所用的原点就变成了 s + n(这个是因为 拆点造成的),而汇点可以通过入边无相接受消息,所以 入边 链接的还是 e (即所用的汇点e不变)

题解(Dinic)

#include<iostream>
#include<cstring>
#include<algorithm>
#include<queue>
using namespace std; #define INF 0x3f3f3f3f
const int maxn = 205;
const int maxm = 2005;
struct Edge
{
int v,w,next;
} edge[2*maxm];
int head[maxm],cur[maxm];
int deep[maxm];
int use[maxm];
int n,m,s,e; int k = -1;
void Add(int u, int v, int w)
{
edge[++ k] = (Edge){ v, w, head[u]}; head[u] = k;
edge[++ k] = (Edge){ u, 0, head[v]}; head[v] = k;
} //来分层用的
bool bfs(int s, int e)
{
for(int i = 0; i <= 2*n; i ++)
cur[i] = head[i], deep[i] = INF, use[i] = 0; deep[s] = 0;
queue<int> q;
q.push(s);
int u,v;
while(! q.empty())
{
u = q.front(); q.pop();
use[u] = 0; for(int i = head[u]; i != -1; i = edge[i].next)
{
v = edge[i].v;
if(edge[i].w && deep[v] == INF)
{
deep[v] = deep[u] + 1;
if(! use[v])
{
q.push(v);
use[v] = 1;
}
}
}
}
if(deep[e] == INF)
return false;
return true;
} int dfs(int now, int e, int limit)
{
if(! limit || now == e) return limit;
int flow = 0,f;
for(int i = cur[now]; i != -1; i = edge[i].next)
{
if(deep[edge[i].v] == deep[now] + 1 && (f = dfs(edge[i].v, e, min(limit, edge[i].w))))
{
cur[now] = i; //当前弧优化
flow += f;
limit -= f;
edge[i].w -= f;
edge[i^1].w += f;
if(! limit)
break;
}
}
return flow;
} int Dinic(int s, int e)
{
int mx_flw = 0;
while(bfs(s, e))
mx_flw += dfs(s, e, INF);
return mx_flw;
} void init()
{
k = -1;
memset(head, -1, sizeof(head));
} int main()
{
ios::sync_with_stdio(false);
//freopen("T.txt","r",stdin);
cin >> n >> m >> s >> e;
s += n;
init();
//拆点操作
for(int i = 1; i <= n; i ++)
Add(i, i + n, 1);
int u, v;
for(int i = 1; i <= m; i ++)
cin >> u >> v, Add(u + n, v, INF), Add(v + n, u, INF); cout << Dinic(s, e) << endl; return 0;
}

P1345 [USACO5.4]奶牛的电信(点拆边 + 网络最小割)的更多相关文章

  1. P1345 [USACO5.4]奶牛的电信Telecowmunication

    P1345 [USACO5.4]奶牛的电信Telecowmunication 题目描述 农夫约翰的奶牛们喜欢通过电邮保持联系,于是她们建立了一个奶牛电脑网络,以便互相交流.这些机器用如下的方式发送电邮 ...

  2. 洛谷P1345 [USACO5.4]奶牛的电信Telecowmunication【最小割】分析+题解代码

    洛谷P1345 [USACO5.4]奶牛的电信Telecowmunication[最小割]分析+题解代码 题目描述 农夫约翰的奶牛们喜欢通过电邮保持联系,于是她们建立了一个奶牛电脑网络,以便互相交流. ...

  3. 洛谷——P1345 [USACO5.4]奶牛的电信Telecowmunication

    P1345 [USACO5.4]奶牛的电信Telecowmunication 题目描述 农夫约翰的奶牛们喜欢通过电邮保持联系,于是她们建立了一个奶牛电脑网络,以便互相交流.这些机器用如下的方式发送电邮 ...

  4. [Luogu P1345] [USACO5.4]奶牛的电信Telecowmunication (最小割)

    题面 传送门:https://www.luogu.org/problemnew/show/P1345 ] Solution 这道题,需要一个小技巧了解决. 我相信很多像我这样接蒟蒻,看到这道题,不禁兴 ...

  5. 洛谷P1345 [USACO5.4]奶牛的电信 [最小割]

    题目传送门 奶牛的电信 题目描述 农夫约翰的奶牛们喜欢通过电邮保持联系,于是她们建立了一个奶牛电脑网络,以便互相交流.这些机器用如下的方式发送电邮:如果存在一个由c台电脑组成的序列a1,a2,..., ...

  6. 洛谷P1345 [USACO5.4]奶牛的电信(最小割)

    题目描述 农夫约翰的奶牛们喜欢通过电邮保持联系,于是她们建立了一个奶牛电脑网络,以便互相交流.这些机器用如下的方式发送电邮:如果存在一个由c台电脑组成的序列a1,a2,...,a(c),且a1与a2相 ...

  7. 洛谷P1345 [USACO5.4]奶牛的电信Telecowmunication(最小割)

    题目描述 农夫约翰的奶牛们喜欢通过电邮保持联系,于是她们建立了一个奶牛电脑网络,以便互相交流.这些机器用如下的方式发送电邮:如果存在一个由c台电脑组成的序列a1,a2,...,a(c),且a1与a2相 ...

  8. 洛谷 P1345 [USACO5.4]奶牛的电信Telecowmunication

    题目描述 农夫约翰的奶牛们喜欢通过电邮保持联系,于是她们建立了一个奶牛电脑网络,以便互相交流.这些机器用如下的方式发送电邮:如果存在一个由c台电脑组成的序列a1,a2,...,a(c),且a1与a2相 ...

  9. P1345 [USACO5.4]奶牛的电信[拆点+最小割]

    题目描述 农夫约翰的奶牛们喜欢通过电邮保持联系,于是她们建立了一个奶牛电脑网络,以便互相交流.这些机器用如下的方式发送电邮:如果存在一个由c台电脑组成的序列a1,a2,...,a(c),且a1与a2相 ...

随机推荐

  1. (26)ASP.NET Core EF保存(基本保存、保存相关数据、级联删除、使用事务)

    1.简介 每个上下文实例都有一个ChangeTracker,它负责跟踪需要写入数据库的更改.更改实体类的实例时,这些更改会记录在ChangeTracker中,然后在调用SaveChanges时会被写入 ...

  2. Oracle批量插入有日期类型数据

    例如现在有张表 id(number) startTime(date) name(varchar2) 1 2017-08-13  zhangsan 2 2017-08-14  zhangsan 需要批量 ...

  3. Oracle根据实体类比对2个数据库结构差异(demo)

    源起 在公司做项目时 经常出现 实体结构和线上的数据结构以及公司开发库数据结构不匹配的问题 但是又不能直接把开发库导入到生产库因为生产库已经有实际数据了 所以弄了一个小工具 此处只做记录用 demo级 ...

  4. Redis01——Redis究竟支持哪些数据结构

    Redis已经越来越多地应用到互联网技术中,而关于Redis的相关问题,也成为面试中必不可少的一部分,本文开始将会逐渐把我了解到的关于Redis的一些面试问题整理出来,供各位参考,如有不对之处,烦请指 ...

  5. 五分钟学Java:如何才能学好Java Web里这么多的技术

    原创声明 本文作者:黄小斜 转载请务必在文章开头注明出处和作者. 系列文章介绍 本文是<五分钟学Java>系列文章的一篇 本系列文章主要围绕Java程序员必须掌握的核心技能,结合我个人三年 ...

  6. Vue2.0 【第二季】第8节 Component 父子组件关系

    目录 Vue2.0 [第二季]第8节 Component 父子组件关系 第8节 Component 父子组件关系 一.构造器外部写局部注册组件 二.父子组件的嵌套 Vue2.0 [第二季]第8节 Co ...

  7. 《JavaScript 模式》读书笔记(2)— 基本技巧3

    这是基本技巧的最后一篇内容,这篇内容示例代码并不多.主要是概念比较多一点. 编码约定 确定并一致遵循约定比这个具体约定是什么更为重要. 一.缩进 无论是使用tab还是空格,只要是一致遵循的,是什么并不 ...

  8. Codeforces Round #200 (Div. 2)E

    Read Time 题意:有一个数组,很多指针指在这个数组上,每次每个指针可以向左或向右移动一个位置.给出一些需要访问的位置,问访问用的最少时间. 一个指针只可能转一次方向.二分答案. #includ ...

  9. JavaScript表单序列化的方法详解

    本文介绍下,在javascript中实现表单序列化的方法,通过实例加深理解,有需要的朋友参考下吧. 在JavaScript中,可以利用表单字段的type属性,连同name和value属性一起实现对表单 ...

  10. 【Weiss】【第04章】AVL树例程

    普通的二叉搜索树可能会由于数据不平均.删除产生高度差等原因,使树倾向于不平衡生长,导致操作慢于O(NlogN). 为应对此现象,将搜索.删除.插入的最坏时间也控制在O(NlogN)上,产生了平衡二叉树 ...