UVa 10480:Sabotage (最小割集)
https://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&page=show_problem&problem=1421
题意:给出n个点m条边,每条边有一个花费,问将1和2隔离需要破坏的边的最小花费的边集。
思路:很明显是最小割,但是问题在于如何求出这个最小割集。通过以前的题目,求网络的最大流就是求网络的最小割,那么从源点到汇点的最大流必定就会经过最小割集的边,当这条边满载(flow == cap)的时候,这条边其实就是最小割集的边。求出最大流之后,整个残余网络会被分成两个集合,一个和源点直接间接相连的点集,另一个和汇点直接间接相连的点集,所以只要BFS从源点或者汇点往前扫,一边扫一边标记,直到扫到(flow == cap)的边就停止。然后枚举边,如果一条边有一边的顶点是被标记过的,另一边的顶点没被标记,那么这条边就是最小割集之一了。
#include <cstdio>
#include <cstring>
#include <cmath>
#include <cstdlib>
#include <algorithm>
#include <string>
#include <iostream>
#include <stack>
#include <map>
#include <queue>
#include <set>
using namespace std;
typedef long long LL;
#define N 55
#define M 505
#define INF 0x3f3f3f3f
struct Edge {
int u, v, cap;
Edge () {}
Edge (int u, int v, int cap) : u(u), v(v), cap(cap) {}
} edge[M*];
vector<int> G[N];
int dis[N], cur[N], S, T, tot, vis[N], mp[N][N]; void Add(int u, int v, int cap) {
edge[tot] = Edge(u, v, cap);
G[u].push_back(tot++);
edge[tot] = Edge(v, u, );
G[v].push_back(tot++);
} int BFS() {
memset(dis, INF, sizeof(dis));
queue<int> que;
que.push(S); dis[S] = ;
while(!que.empty()) {
int u = que.front(); que.pop();
for(int i = ; i < G[u].size(); i++) {
Edge &e = edge[G[u][i]];
if(dis[e.v] == INF && e.cap > ) {
dis[e.v] = dis[u] + ;
que.push(e.v);
}
}
}
return dis[T] < INF;
} int DFS(int u, int maxflow) {
if(u == T) return maxflow;
for(int i = cur[u]; i < G[u].size(); i++) {
cur[u] = i;
Edge &e = edge[G[u][i]];
if(dis[e.v] == dis[u] + && e.cap > ) {
int flow = DFS(e.v, min(e.cap, maxflow));
if(flow > ) {
e.cap -= flow;
edge[G[u][i]^].cap += flow;
return flow;
}
}
}
return ;
} int Dinic() {
int ans = ;
while(BFS()) {
int flow;
memset(cur, , sizeof(cur));
while(flow = DFS(S, INF)) ans += flow;
}
return ans;
} void bfs() {
queue<int> que;
que.push(S); vis[S] = ;
while(!que.empty()) {
int u = que.front(); que.pop();
for(int i = ; i < G[u].size(); i++) {
Edge &e = edge[G[u][i]];
if(!vis[e.v] && e.cap > ) {
vis[e.v] = ;
que.push(e.v);
}
}
}
} int main()
{
int n, m;
while(~scanf("%d%d", &n, &m), n + m) {
int u, v, cap; tot = ;
for(int i = ; i <= n; i++) G[i].clear();
memset(mp, , sizeof(mp));
memset(vis, , sizeof(vis));
for(int i = ; i < m; i++) {
scanf("%d%d%d", &u, &v, &cap);
Add(u, v, cap); Add(v, u, cap);
} S = , T = ;
Dinic();
bfs();
for(int u = ; u <= n; u++) {
for(int i = ; i < G[u].size(); i++) {
int v = edge[G[u][i]].v;
if(vis[u] && !vis[v] || vis[v] && !vis[u]) mp[u][v] = mp[v][u] = ;
}
}
for(int i = ; i <= n; i++) {
for(int j = i + ; j <= n; j++) {
if(mp[i][j]) printf("%d %d\n", i, j);
}
}
puts("");
}
return ;
}
UVa 10480:Sabotage (最小割集)的更多相关文章
- UVA - 10480 Sabotage 最小割,输出割法
UVA - 10480 Sabotage 题意:现在有n个城市,m条路,现在要把整个图分成2部分,编号1,2的城市分成在一部分中,拆开每条路都需要花费,现在问达成目标的花费最少要隔开那几条路. 题解: ...
- UVA 10480 Sabotage (网络流,最大流,最小割)
UVA 10480 Sabotage (网络流,最大流,最小割) Description The regime of a small but wealthy dictatorship has been ...
- UVA - 10480 Sabotage【最小割最大流定理】
题意: 把一个图分成两部分,要把点1和点2分开.隔断每条边都有一个花费,求最小花费的情况下,应该切断那些边.这题很明显是最小割,也就是最大流.把1当成源点,2当成汇点,问题是要求最小割应该隔断那条边. ...
- UVA 10480 Sabotage (最大流) 最小割边
题目 题意: 编写一个程序,给定一个网络规范和破坏每个连接的成本,确定要切断哪个连接,以便将首都和最大的城市分离到尽可能低的成本. 分割-------------------------------- ...
- Uva 10480 Sabotage 最大流
表示自从学了网络流,就基本上是一直用dinic 这个题一看就是用最大流,作为常识,两个点之间的最大流等于最小割 但是这个题需要输出割边,然后我就不会了,dinic判流量我觉得也可做,但是一直wa 然后 ...
- UVA 10480 Sabotage
最小割+输出方案 #include<cstdio> #include<cstring> #include<string> #include<cmath> ...
- UVA - 10480 Sabotage (Dinic)
The regime of a small but wealthy dictatorship has been abruptly overthrown by an unexpected rebel-l ...
- UVA 10480 Sabotage (最大流最小割)
题目链接:点击打开链接 题意:把一个图分成两部分,要把点1和点2分开.隔断每条边都有一个花费,求最小花费的情况下,应该切断那些边. 这题很明显是最小割,也就是最大流.把1当成源点,2当成汇点. 问题是 ...
- hiho 第116周,最大流最小割定理,求最小割集S,T
小Hi:在上一周的Hiho一下中我们初步讲解了网络流的概念以及常规解法,小Ho你还记得内容么? 小Ho:我记得!网络流就是给定了一张图G=(V,E),以及源点s和汇点t.每一条边e(u,v)具有容量c ...
随机推荐
- 用C语言编写Windows服务程序的五个步骤
Windows 服务被设计用于需要在后台运行的应用程序以及实现没有用户交互的任务.为了学习这种控制台应用程序的基础知识,C(不是C++)是最佳选择.本文将建立并实现一个简单的服务程序,其功能是查询系统 ...
- vagrant up default: Warning: Authentication failure. Retrying...的一些解决办法
vagrant up default: Warning: Authentication failure. Retrying...的一些解决办法 一般看到这个信息时,虚拟机已经启动成功,可以中断命令后v ...
- JS 数组两种定义方式
<!DOCTYPE html><html lang="en" xmlns="http://www.w3.org/1999/xhtml"> ...
- jquery 包裹标签
<!DOCTYPE html><html><head><meta http-equiv="Content-Type" content=&q ...
- 如何设置程序UAC控制
在做项目的过程中,有很多情况会涉及到权限问题,要求必须以管理员的身份才能运行,如何强制我们的程序必须以管理员身份运行呢?在调查的过程中发现有很多方式,此处介绍一种简单的方式. 1.在VS中,右键点击工 ...
- ArchLinux 安装记录
主要步骤 下载镜像及刻录 开机安装 联网 编辑镜像站文件 分区 格式化分区并挂载 安装基本操作系统 配置基础操作系统 引导系统 用户管理 网络配置 安装Gonme桌面环境 其他优化 开始准备 下载镜像 ...
- Delphi For Linux Compiler
Embarcadero is about to release a new Delphi compiler for the Linux platform. Here are some of the k ...
- 80%的岗位是没有太多能力上的要求的(少部分聪明的人开始觉醒,这部分一定是那些主动追求、主动学习的人;30岁现象能区分真正专业和不学无术的人)good
不要沦陷程序员的30岁问题 热门> 就是学习能力和工作热情态度的问题. 我之前也跟作者一样思考过这个问题,答案是否定的. 在知识积累的行业,年纪越大,越吃香,比如金融,医学,IT.就怕3 ...
- Hadoop集群(第3期)机器信息分布表
1.分布式环境搭建 采用4台安装Linux环境的机器来构建一个小规模的分布式集群. 图1 集群的架构 其中有一台机器是Master节点,即名称节点,另外三台是Slaver节点,即数据节点.这四台机器彼 ...
- Hadoop集群(第1期)CentOS安装配置
1.准备安装 1.1 系统简介 CentOS 是什么? CentOS是一个基于Red Hat 企业级 Linux 提供的可自由使用的源代码企业级的 Linux 发行版本.每个版本的 CentOS 都会 ...