题目链接:UVA-10480 Sabotage

The regime of a small but wealthy dictatorship has been abruptly overthrown by an unexpected rebellion.
Because of the enormous disturbances this is causing in world economy, an imperialist military
super power has decided to invade the country and reinstall the old regime.
For this operation to be successful, communication between the capital and the largest city must
be completely cut. This is a difficult task, since all cities in the country are connected by a computer
network using the Internet Protocol, which allows messages to take any path through the network.
Because of this, the network must be completely split in two parts, with the capital in one part and
the largest city in the other, and with no connections between the parts.
There are large differences in the costs of sabotaging different connections, since some are much
more easy to get to than others.
Write a program that, given a network specification and the costs of sabotaging each connection,
determines which connections to cut in order to separate the capital and the largest city to the lowest possible cost.

Input

Input file contains several sets of input. The description of each set is given below.
The first line of each set has two integers, separated by a space: First one the number of cities, n in
the network, which is at most 50. The second one is the total number of connections, m, at most 500.
The following m lines specify the connections. Each line has three parts separated by spaces: The
first two are the cities tied together by that connection (numbers in the range 1 − n). Then follows the cost of cutting the connection (an integer in the range 1 to 40000000). Each pair of cites can appear at most once in this list.
Input is terminated by a case where values of n and m are zero. This case should not be processed.
For every input set the capital is city number 1, and the largest city is number 2.

Output

For each set of input you should produce several lines of output. The description of output for each set of input is given below:
The output for each set should be the pairs of cities (i.e. numbers) between which the connection
should be cut (in any order), each pair on one line with the numbers separated by a space. If there is more than one solution, any one of them will do.
Print a blank line after the output for each set of input.

Sample Input

5 8
1 4 30
1 3 70
5 3 20
4 3 5
4 5 15
5 2 10
3 2 25
2 4 50
5 8
1 4 30
1 3 70
5 3 20
4 3 5
4 5 15
5 2 10
3 2 25
2 4 50
0 0

Sample Output

4 1
3 4
3 5
3 2
4 1
3 4
3 5
3 2


题意:

含有n个结点及m条无向边的图,每条边都带有边权(一个正整数),现要删除边使得结点s(编号为1)和t(编号为2)不连通,要令删除的边权之和最小,要求输出被删除的边(以任意顺序输出任意一个满足的方案)


分析:

这是一个最小割问题,由最大流最小割定理可知:s-t 最小割的容量等于 s-t 最大流的流量

那么求最小割就转化为了求最大流,但是要注意,求最小割时是无向图,所以正向边和反向边的初始残量都要等于边权

这题有一个难点,并不是要求输出最小割,而是输出达到最小割时需要割掉的边

因为跑了一遍最大流后,图会被分成两部分(结点s所在的部分和结点t所在的部分),所以只需要先预处理一下哪些点所在部分不同,然后遍历所有边,起点、终点所在部分不同的边即是需要割掉的边。(为方便处理,建图时要记录边的起点和终点)


以下代码:

#include<iostream>
#include<cstdio>
#include<cstring>
#include<string>
#include<queue>
#include<map>
#include<algorithm>
#define LL long long
using namespace std;
const int INF=0x3f3f3f3f;
const int maxn=1e2+50;
const int maxm=1e3+50;
struct edge
{int w;int from;int to;int next;
}e[maxm];
int head[maxn],cnt;
int s,t;
int n,m;
void addedge(int u,int v,int w)
{e[cnt].from=u;e[cnt].w=w;e[cnt].to=v;e[cnt].next=head[u];head[u]=cnt;cnt++;
}
int dis[maxn];     //dis数组记录层次
bool bfs()         //利用BFS建立分成图,从而可以多次DFS增广
{memset(dis,-1,sizeof(dis));     //初始化dis数组queue<int> q;q.push(s);dis[s]=0;      //源点层次为0while(!q.empty()){int u=q.front();q.pop();for(int i=head[u];i!=-1;i=e[i].next){int v=e[i].to;if(e[i].w>0&&dis[v]==-1)     //可达&&未分层{dis[v]=dis[u]+1;         //分层if(v==t)                 //若到达汇点,则分层结束,返回truereturn true;q.push(v);}}}return false;  //运行到此处,说明汇点已不可达,返回false
}
int cur[maxn];     //弧优化:cur数组用于记录上一次DFS增广时u已经增广到第几条边,从而优化时间
int dfs(int u,int flow)       //flow代表流入u点的最大流量
{if(u==t)return flow;          //到达汇点,直接返回flowfor(int &i=cur[u];i!=-1;i=e[i].next){                         //注意i前面用&引用,这样就可以直接改变cur[u]int v=e[i].to;if(dis[v]==dis[u]+1&&e[i].w>0)   //v为u的下一层&&可达{int k=dfs(v,min(flow,e[i].w));if(k>0){e[i].w-=k;         //正向边-=ke[i^1].w+=k;       //反向边+=kreturn k;}}}return 0;       //无法继续增广,返回0
}int dinic()
{int ans=0;      //记录总流量while(bfs())    //分层{for(int i=0;i<maxn;i++)    //初始化cur数组,即将head数组赋给cur数组cur[i]=head[i];while(int k=dfs(s,INF))    //增广ans+=k;}return ans;
}
bool vis[maxn];
void dfs_again(int u)
{if(vis[u])return;elsevis[u]=true;for(int i=head[u];i!=-1;i=e[i].next){if(e[i].w>0)        //残量>0才能通过dfs_again(e[i].to);}
}
int main()
{while(scanf("%d %d",&n,&m)&&n+m){memset(head,-1,sizeof(head));cnt=0;s=1;t=2;for(int i=1;i<=m;i++){int u,v,w;scanf("%d %d %d",&u,&v,&w);addedge(u,v,w);addedge(v,u,w);}dinic();memset(vis,false,sizeof(vis));dfs_again(s);            //遍历一遍s所在部分,加上标记bool flag[maxm]={false};for(int i=0;i<cnt;i++)   //遍历所有边{if(flag[i])continue;int u=e[i].from,v=e[i].to;if((!vis[u]&&vis[v])||(!vis[v]&&vis[u])){printf("%d %d\n",u,v);flag[i]=true;flag[i^1]=true;  //防止多输出一次反向边}}printf("\n");}return 0;
}

UVA-10480 Sabotage(最大流最小割定理+输出路径)相关推荐

  1. UVA - 10480 Sabotage 最小割,输出割法

    UVA - 10480 Sabotage 题意:现在有n个城市,m条路,现在要把整个图分成2部分,编号1,2的城市分成在一部分中,拆开每条路都需要花费,现在问达成目标的花费最少要隔开那几条路. 题解: ...

  2. UVA - 10480 Sabotage(最小割-最大流+输出割边)

    题目链接:点击查看 题目大意:给出一张无向图,1为起点,2为终点,删除每条边都需要权值wi,题目需要求将起点与终点分割为两个部分的最小花费,并且输出方案 题目分析:如果不让输出方案的话就是一个裸的最大 ...

  3. hihocoder 网络流二·最大流最小割定理

    网络流二·最大流最小割定理 时间限制:10000ms 单点时限:1000ms 内存限制:256MB 描述 小Hi:在上一周的Hiho一下中我们初步讲解了网络流的概念以及常规解法,小Ho你还记得内容么? ...

  4. nyoj 677 碟战(最大流最小割定理)

    碟战 时间限制:2000 ms  |  内存限制:65535 KB 难度:4 描述 知己知彼,百战不殆!在战争中如果被敌人掌握了自己的机密,失败是必然的.K国在一场战争中屡屡失败,就想到自己的某些城市 ...

  5. GraphCut、最大流最小割定理

    G=(V,E):V为点集,E为边集: 节点集V中的节点分为: (1)终端节点.不包含图像像素,用S和T表示.S为源点,T为汇点.图像分割中通常用S表示前景目标,标签设为1:T表示背景,标签为0. (2 ...

  6. 流网络的最小割问题c语言,网络流基础-最大流最小割定理

    最大流最小割定理,指网络流的最大流等于其最小割. 最大流指符合三个性质的前提下,从S到T能流过的最大流量. 最小割指符合割的定义,最小的割容量. 求最大流: 不断寻找增广路,计算能增加的最小流量,然后 ...

  7. 最大流最小割定理(max flow/min cut theory)

    百度文库里面有个地址,讲的比较详细. http://wenku.baidu.com/link?url=gPXhYCduLNgZaOkKIltNDAgPGwuMTpRX7a0utvVFuqDAP9o1j ...

  8. Cable TV Network POJ - 1966 最大流最小割定理 点边转化

    最大流最小割定理 任何一个网络的最大流量等于最小割中边的容量之和 即最大流等于最小割 点边转化 节点可以拆为入点和出点 把点的属性添加到入点和出点之间的边上 图的边也可以分两截 在中间加一个节点 把边 ...

  9. UVA - 10480 Sabotage 输出最小割方案

    题目链接 https://vjudge.net/problem/UVA-10480 题意 无向图求最小割的方案 思路 最小割部分是模版,问题在于最小割的方案如何输出. 首先根据最小割最大流定理,我们跑 ...

最新文章

  1. HttpClient:绕开https证书(三)
  2. wxWidgets:wxFileName类用法
  3. 深度对比Python的3种“字符串格式化”方法,看看你喜欢哪一种?
  4. 什么是alpha测试_什么是ALPHA?
  5. trie树查找前缀串_Trie数据结构(前缀树)
  6. java学习(105):字符串indexof,spilt,substring方法
  7. html中的ppt文字不清晰,HTML页面的文字布局与文字效果.ppt
  8. 马云身家将超4800亿!蚂蚁集团IPO发行价出炉,总市值达2.1万亿
  9. 入门 | 神经网络词嵌入:如何将《战争与和平》表示成一个向量?
  10. 数据结构 静态队列笔记
  11. C++中10的N次方如何表示
  12. python练习题003:圆的面积
  13. 如何清理多余的Windows桌面右键菜单
  14. 使用esp8266前的网络基础
  15. 9860测量程序(最后结果)1
  16. Pathon安装教程环境配置教程(Pathon2.7和3.7的区别)
  17. 公司注销又有新变化! 财务人要知道的公司注销新规定
  18. 因为在此系统上禁止运行脚本。有关详细信息,请参阅
  19. 智能存储 | 视频增强“全家桶”,为您的视频快速“换脸”
  20. Protobuf 介绍与实战30:google/protbuf/any.proto, api.proto, descriptor.proto,empty.proto 在什么位置

热门文章

  1. 微信公众平台显示隐藏网页右上角菜单(第九课)
  2. 1h2g云服务器做网站,云服务器1H2G和1H1G的区别
  3. 国有六大行与农商行的实习比拼
  4. 雷电android game学习笔记(1)
  5. vue.runtime.esm.js?2b0e:1888 TypeError: Cannot read property ‘_wrapper‘ of undefined
  6. win10+ubuntu18.04双系统安装/大集合
  7. php红包退回通知,php 微信红包 返回问题
  8. 公司邮箱注册申请哪个好
  9. 伤害世界服务器连接失败_伤害世界Hurtworld怎么开服 伤害世界Hurtworld服务器开服方法...
  10. Dell笔记本电脑禁用Fn键