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)的更多相关文章

  1. UVA 10480 Sabotage (网络流,最大流,最小割)

    UVA 10480 Sabotage (网络流,最大流,最小割) Description The regime of a small but wealthy dictatorship has been ...

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

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

  3. uva 725 Division(除法)暴力法!

    uva 725  Division(除法) A - 暴力求解 Time Limit:3000MS     Memory Limit:0KB     64bit IO Format:%lld & ...

  4. 混合欧拉回路的判断(Dinic)

    POJ1637 Sightseeing tour Time Limit: 1000MS   Memory Limit: 10000K Total Submissions: 7483   Accepte ...

  5. UVA 11294 Wedding(2-sat)

    2-sat.不错的一道题,学到了不少. 需要注意这么几点: 1.题目中描述的是有n对夫妇,其中(n-1)对是来为余下的一对办婚礼的,所以新娘只有一位. 2.2-sat问题是根据必然性建边,比如说A与B ...

  6. Uva 10480 Sabotage 最大流

    表示自从学了网络流,就基本上是一直用dinic 这个题一看就是用最大流,作为常识,两个点之间的最大流等于最小割 但是这个题需要输出割边,然后我就不会了,dinic判流量我觉得也可做,但是一直wa 然后 ...

  7. P2763 试题库问题(dinic)

    P2763 试题库问题 dinic 搞个虚拟源点和汇点,瞎建建边就好辣. 偷张图↓↓ 如果没满流就是无解辣 输出方案咋办呢? 枚举每种类型,蓝后枚举它们的边 如果该边被使用了(通过判断反向边的流量), ...

  8. UVa 1393 - Highways(数论)

    链接: https://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&page=show_problem& ...

  9. 【UVa】Jump(dp)

    http://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&page=show_problem&p ...

随机推荐

  1. tp5 上传视频到七牛云

    废话少说直接上代码 html <!DOCTYPE html> <html> <head> <title></title> </head ...

  2. 用python爬虫抓站的一些技巧总结 zz

    用python爬虫抓站的一些技巧总结 zz 学用python也有3个多月了,用得最多的还是各类爬虫脚本:写过抓代理本机验证的脚本,写过在discuz论坛中自动登录自动发贴的脚本,写过自动收邮件的脚本, ...

  3. Servlet Cookies

    Cookie是在多个客户端请求之间持久存储的一小段信息. Cookie具有名称,单个值和可选属性,例如注释,路径和域限定符,生存周期和版本号. Cookie工作原理 默认情况下,每个请求都被视为新的请 ...

  4. Oracle安装 卸载 和常见问题

    Oracle的安装   全局数据库名:orcl  口令:orcl 或者以第三方工具SQLplus为例 系统用户:sys 和 system  练习账户:scott (密码:tiger) 登录账户为:sy ...

  5. CoreData遇见iCloud的那些坑

    尽管苹果把iCloud与CoreData之间的完美配合吹的天花乱坠,但在iOS7之前,想用iCloud同步CoreData数据简直就是噩梦,苹果自己也承认了之前的诸多bug和不稳定性,这让苹果不得不重 ...

  6. mysql原来是按自然日统计。怎么可以用今天10点到次日10点这样统计???

    关于网友提出的" mysql原来是按自然日统计.怎么可以用今天10点到次日10点这样统计???"问题疑问,本网通过在网上对" mysql原来是按自然日统计.怎么可以用今天 ...

  7. 配置 IO 时要记得换 Page

    配置 IO 时要记得换 Page 在配置某些芯片时,配置 IO 时要记得换页,不然不生效. 注意查看 IO 的相关规格书说明,而且每个厂商是不一样的.

  8. Java练习 SDUT-2585_机器人II

    机器人II Time Limit: 1000 ms Memory Limit: 65536 KiB Problem Description 自从xiao_wu发明了只能向左转与向右转的机器人以后,热血 ...

  9. dataframe构建

    data=[[[0],1]]df = pd.DataFrame(data, columns=['col1', 'col2']) df = pd.DataFrame({‘col1’:‘’,‘col2’: ...

  10. day5-python之面向过程编程

    一.面向过程编程 #1.首先强调:面向过程编程绝对不是用函数编程这么简单,面向过程是一种编程思路.思想,而编程思路是不依赖于具体的语言或语法的.言外之意是即使我们不依赖于函数,也可以基于面向过程的思想 ...