题目描述

农夫约翰的奶牛们喜欢通过电邮保持联系,于是她们建立了一个奶牛电脑网络,以便互相交流。这些机器用如下的方式发送电邮:如果存在一个由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. vue 打包体积过大 实现懒加载 ????

    import Vue from ‘vue’ import Router from 'vue-router' //把路由对应的组件定义成异步组纪检 const hello = resolve => ...

  2. ElasticSearch 6.2.4 实践

    参考资料 ElasticSearch 官网 ElasticSearch,Kibana,Asp.net Core with docker 示例 阮一峰 ElasticSearch 基础概念 索引(ind ...

  3. JVM05——JVM类加载机制知多少

    我们已经讲过 JVM 相关的很多常见知识点,感兴趣的朋友可以在我的往期文章中查看.接下来将继续为各位带来 JVM 类加载机制.关注我的公众号「Java面典」了解更多 Java 相关知识点. 类生命周期 ...

  4. python3:input() 函数

    一.知识介绍: 1.input() 函数,接收任意输入,将所有输入默认为字符串处理,并返回字符串类型: 2.可以用作文本输入,如用户名,密码框的值输入: 3.语法:input("提示信息:& ...

  5. 附014.Kubernetes Prometheus+Grafana+EFK+Kibana+Glusterfs整合解决方案

    一 glusterfs存储集群部署 注意:以下为简略步骤,详情参考<附009.Kubernetes永久存储之GlusterFS独立部署>. 1.1 架构示意 略 1.2 相关规划 主机 I ...

  6. svn 追责神器 blame vscode - SVN Gutter

    svn 追责神器 blame vscode - SVN Gutter

  7. iview mock main.js

    main.js // 实际打包时应该不引入mock /* eslint-disable */ // if (process.env.NODE_ENV !== 'production') require ...

  8. 移动端Rem适配(基于vue-cli3 ,ui框架用的是vant-ui)

    介绍postcss-pxtorem 是一款 postcss 插件,用于将单位转化为 remlib-flexible 用于设置 rem 基准值 1.安装lib-flexible(用于设置 rem 基准值 ...

  9. 手写 Promise 符合 Promise/A+规范

    异步编程是前端开发者必需的技能,过去管理异步的主要机制都是通过函数回调,然而会出现像“回调地狱”这样的问题.为了更好的管理回调,ES6 增加了一个新的特性 Promise.Promise 是 ES7 ...

  10. postman集合测试执行

    postman工具可以运用集合管理接口请求,特别适合某业务流程的集合请求管理. 如果单个请求诸葛send,耗时费力,可以直接以集合运行 一,运行方法: 1,选中集合--点击右侧小箭头--显示页面中点击 ...