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 ...
随机推荐
- 安装Eclipse完PyDev插件中没有出现
假设你是在Window7在环境搭建.请确保您使用以管理员身份运行Eclipse. PyDev插件安装后没有显示是由于PyDev的执行须要Java7,能够通过升级JDK的版本号来完毕,而且配置环境变量( ...
- abp框架(aspnetboilerplate)扩展系统表
以OrganizationUnit为例,进行扩展,加入IsUse属性 1.创建一个新类,比如ExtendedOrganizationUnit,继承OrganizationUnit public cla ...
- 有了VARCHAR,为什么还要有CHAR?
VarcharVarchar往往用来保存可变长度的字符串.简单的说,我们只是给其固定了一个最大值,然后系统会根据实际存储的数据量来分配合适的存储空间.为此相比CHAR字符数据而言,其能够比固定长度类型 ...
- XF相对布局
using System; using Xamarin.Forms; using Xamarin.Forms.Xaml; [assembly: XamlCompilation (XamlCompila ...
- jquery 相对元素
<!DOCTYPE html><html><head><meta http-equiv="Content-Type" content=&q ...
- jquery 用json设置css
<!DOCTYPE html><html><head><meta http-equiv="Content-Type" content=&q ...
- WPF中ItemsControl应用虚拟化时找到子元素的方法
原文:WPF中ItemsControl应用虚拟化时找到子元素的方法 wpf的虚拟化技术会使UI的控件只初始化看的到的子元素, 而不是所有子元素都被初始化,这样会提高UI性能. 但是我们经常会遇到一个 ...
- GIS基础软件及操作(六)
原文 GIS基础软件及操作(六) 练习六.空间分析的应用 1.加深对缓冲区分析基本原理.方法的认识:2.熟练掌握距离制图创建缓冲区技术方法.3.掌握利用缓冲区分析方法解决地学空间分析问题的能力. 1. ...
- GzipStream的简单使用压缩和解压
压缩和解压都需要用到三个流实例,分别是文件读取流.文件写入流.压缩流. 读取流和写入流有多种形式,压缩流就一种GzipStream. 不同的是对于压缩,是需要用文件写入流作为创建压缩流实例的参数, 压 ...
- nyoj7——街区最短问题
描述 一个街区有很多住户,街区的街道只能为东西.南北两种方向. 住户只可以沿着街道行走. 各个街道之间的间隔相等. 用(x,y)来表示住户坐在的街区. 例如(4,20),表示用户在东西方向第4个街道, ...