UVA - 10480 Sabotage (Dinic)
The regime of a small but wealthy dictatorship has been abruptly overthrown by an unexpected rebel-
lion. 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.
题意:
求图的最小割的可能方案。
思路:
暴力枚举每一条边,边的全值是否是w,判断删除之后最大流是否会减少w,如果会的话,那就真的删了它,否则还原图。
#include<iostream>
#include<algorithm>
#include<vector>
#include<stack>
#include<queue>
#include<map>
#include<set>
#include<cstdio>
#include<cstring>
#include<cmath>
#include<ctime> #define fuck(x) cerr<<#x<<" = "<<x<<endl;
#define debug(a, x) cerr<<#a<<"["<<x<<"] = "<<a[x]<<endl;
#define ls (t<<1)
#define rs ((t<<1)|1)
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
const int maxn = ;
const int maxm = ;
const int inf = 0x3f3f3f3f;
const ll Inf = ;
const int mod = ;
const double eps = 1e-;
const double pi = acos(-); int Head[maxn],cnt;
struct edge{
int Next,u,v;
int w;
}e[maxm];
void add_edge(int u,int v,int w){
e[cnt].Next=Head[u];
e[cnt].v=v;
e[cnt].u=u;
e[cnt].w=w;
Head[u]=cnt++;
}
int n,m; int D_vis[maxn],D_num[maxn];
int source,meeting;
bool bfs()
{
memset(D_vis,,sizeof(D_vis));
for(int i=;i<=n;i++){//注意要覆盖所有点
D_num[i]=Head[i];
}
D_vis[source]=;
queue<int>q;
q.push(source);
int r=;
while(!q.empty()){
int u=q.front();
q.pop();
int k=Head[u];
while(k!=-){
if(!D_vis[e[k].v]&&e[k].w){
D_vis[e[k].v]=D_vis[u]+;
q.push(e[k].v);
}
k=e[k].Next;
}
}
return D_vis[meeting];
}
int dfs(int u,int f)
{
if(u==meeting){return f;}
int &k=D_num[u];
while(k!=-){
if(D_vis[e[k].v]==D_vis[u]+&&e[k].w){
int d=dfs(e[k].v,min(f,e[k].w));
if(d>){
e[k].w-=d;
e[k^].w+=d;
return d;
}
}
k=e[k].Next;
}
return ;
}
int Dinic()
{
int ans=;
while(bfs()){
int f;
while((f=dfs(source,inf))>){
ans+=f;
}
}
return ans;
} int main() {
// ios::sync_with_stdio(false);
// freopen("in.txt", "r", stdin);
while (scanf("%d%d",&n,&m)!=EOF&&n){
memset(Head,-,sizeof(Head));
cnt=;
source=;meeting=;
for(int i=;i<=m;i++){
int x,y,z;
scanf("%d%d%d",&x,&y,&z);
add_edge(x,y,z);
add_edge(y,x,z);
} int tot = Dinic();
for(int j=;j<cnt;j+=){
e[j].w=e[j^].w=(e[j].w+e[j^].w)/;
} for(int i=;i<cnt;i+=){
int w = e[i].w;
e[i].w=e[i^].w=;
int tmp = Dinic(); // fuck(tmp)
for(int j=;j<cnt;j+=){
e[j].w=e[j^].w=(e[j].w+e[j^].w)/;
}
if(w==tot - tmp){
printf("%d %d\n",e[i].u,e[i].v);
tot=tmp;
}
else e[i].w=e[i^].w=w; if(tot<=){ break;} }
printf("\n");
} return ;
}
看了网上的题解,发现了更好的方案。
求出最大流之后,图上的点已经被分为了两部分,连接两个部分的边就是一种可能的方案。
#include<iostream>
#include<algorithm>
#include<vector>
#include<stack>
#include<queue>
#include<map>
#include<set>
#include<cstdio>
#include<cstring>
#include<cmath>
#include<ctime> #define fuck(x) cerr<<#x<<" = "<<x<<endl;
#define debug(a, x) cerr<<#a<<"["<<x<<"] = "<<a[x]<<endl;
#define ls (t<<1)
#define rs ((t<<1)|1)
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
const int maxn = ;
const int maxm = ;
const int inf = 0x3f3f3f3f;
const ll Inf = ;
const int mod = ;
const double eps = 1e-;
const double pi = acos(-); int Head[maxn],cnt;
struct edge{
int Next,u,v;
int w;
}e[maxm];
void add_edge(int u,int v,int w){
e[cnt].Next=Head[u];
e[cnt].v=v;
e[cnt].u=u;
e[cnt].w=w;
Head[u]=cnt++;
}
int n,m; int D_vis[maxn],D_num[maxn];
int source,meeting;
bool bfs()
{
memset(D_vis,,sizeof(D_vis));
for(int i=;i<=n;i++){//注意要覆盖所有点
D_num[i]=Head[i];
}
D_vis[source]=;
queue<int>q;
q.push(source);
int r=;
while(!q.empty()){
int u=q.front();
q.pop();
int k=Head[u];
while(k!=-){
if(!D_vis[e[k].v]&&e[k].w){
D_vis[e[k].v]=D_vis[u]+;
q.push(e[k].v);
}
k=e[k].Next;
}
}
return D_vis[meeting];
}
int dfs(int u,int f)
{
if(u==meeting){return f;}
int &k=D_num[u];
while(k!=-){
if(D_vis[e[k].v]==D_vis[u]+&&e[k].w){
int d=dfs(e[k].v,min(f,e[k].w));
if(d>){
e[k].w-=d;
e[k^].w+=d;
return d;
}
}
k=e[k].Next;
}
return ;
}
int Dinic()
{
int ans=;
while(bfs()){
int f;
while((f=dfs(source,inf))>){
ans+=f;
}
}
return ans;
} int main() {
// ios::sync_with_stdio(false);
// freopen("in.txt", "r", stdin);
while (scanf("%d%d",&n,&m)!=EOF&&n){
memset(Head,-,sizeof(Head));
cnt=;
source=;meeting=;
for(int i=;i<=m;i++){
int x,y,z;
scanf("%d%d%d",&x,&y,&z);
add_edge(x,y,z);
add_edge(y,x,z);
}
Dinic();
bfs();
for(int i=;i<=n;i++){
D_vis[i]=min(D_vis[i],);
}
for(int i=;i<cnt;i+=){
if(D_vis[e[i].u]!=D_vis[e[i].v]){
printf("%d %d\n",e[i].u,e[i].v);
}
}
printf("\n");
}
return ;
}
UVA - 10480 Sabotage (Dinic)的更多相关文章
- UVA 10480 Sabotage (网络流,最大流,最小割)
UVA 10480 Sabotage (网络流,最大流,最小割) Description The regime of a small but wealthy dictatorship has been ...
- UVA - 10480 Sabotage 最小割,输出割法
UVA - 10480 Sabotage 题意:现在有n个城市,m条路,现在要把整个图分成2部分,编号1,2的城市分成在一部分中,拆开每条路都需要花费,现在问达成目标的花费最少要隔开那几条路. 题解: ...
- uva 725 Division(除法)暴力法!
uva 725 Division(除法) A - 暴力求解 Time Limit:3000MS Memory Limit:0KB 64bit IO Format:%lld & ...
- 混合欧拉回路的判断(Dinic)
POJ1637 Sightseeing tour Time Limit: 1000MS Memory Limit: 10000K Total Submissions: 7483 Accepte ...
- UVA 11294 Wedding(2-sat)
2-sat.不错的一道题,学到了不少. 需要注意这么几点: 1.题目中描述的是有n对夫妇,其中(n-1)对是来为余下的一对办婚礼的,所以新娘只有一位. 2.2-sat问题是根据必然性建边,比如说A与B ...
- Uva 10480 Sabotage 最大流
表示自从学了网络流,就基本上是一直用dinic 这个题一看就是用最大流,作为常识,两个点之间的最大流等于最小割 但是这个题需要输出割边,然后我就不会了,dinic判流量我觉得也可做,但是一直wa 然后 ...
- P2763 试题库问题(dinic)
P2763 试题库问题 dinic 搞个虚拟源点和汇点,瞎建建边就好辣. 偷张图↓↓ 如果没满流就是无解辣 输出方案咋办呢? 枚举每种类型,蓝后枚举它们的边 如果该边被使用了(通过判断反向边的流量), ...
- UVa 1393 - Highways(数论)
链接: https://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&page=show_problem& ...
- 【UVa】Jump(dp)
http://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&page=show_problem&p ...
随机推荐
- 好玩又实用,阿里巴巴开源混沌工程工具 ChaosBlade
减少故障的最好方法就是让问题经常性的发生.在可控范围或环境下,通过不断重复失败过程,持续提升系统的容错和弹性能力. 那么,实施一次高效的混沌工程实验,需要几步呢? 答案:2 步. ① 登陆 Chaos ...
- Linux使用及命令
#命令模式下输入:光标移动到第34行第15个字符 <Enter>15l(这是小写的L) ctrl+u删除光标前面的字符 ctrl+j删除光标后面的字符 在Linux下用VIM打开大小几个G ...
- hdu1564 简单博弈
多画几个图可以发现规律: #include<stdio.h> int main() { int i,n; while(scanf("%d",&n)!=EOF) ...
- iOS 内存管理arc
http://www.tekuba.net/program/346/ ios自动释放池(autoreleasepool #import <Foundation/Foundation.h> ...
- ef core 随记
EntityTypeConfiguration internal class OrderEntityTypeConfiguration : IEntityTypeConfiguration<Or ...
- MAYA安装失败怎样卸载重新安装MAYA,解决MAYA安装失败的方法总结
技术帖:MAYA没有按照正确方式卸载,导致MAYA安装失败.楼主也查过网上关于如何解决MAYA安装失败的一些文章,是说删除几个MAYA文件和MAYA软件注册表就可以解决MAYA安装失败的问题,实际的情 ...
- spring boot初步
spring boot介绍 Spring Boot 是由 Pivotal 团队提供的全新框架,其设计目的是用来简化新 Spring 应用的初始搭建以及开发过程. 该框架使用了特定的方式来进行配置,从而 ...
- Python基础:07迭代器
迭代器是在版本 2.2 被加入Python 的,它为类序列对象提供了一个类序列的接口.Python 的迭代无缝地支持序列对象,而且它还允许迭代非序列类型,包括用户定义的对象.它的出现,对列表迭代.字典 ...
- laravel 的路由中间件
简介# Laravel 中间件提供了一种方便的机制来过滤进入应用的HTTP请求.例如,Laravel 内置了一个中间件来验证用户的身份认证 , 如果没有通过身份认证,中间件会将用户重定向到登陆界面,但 ...
- Nova中的Hook机制
Nova的代码中支持Hook机制,也就是在某些函数的前后,可以加入自己的代码逻辑.Hook代码可以完全独立于Nova开发,本质上使用setuptools的entry points机制.K版本的Open ...