题目链接:https://cn.vjudge.net/problem/UVA-10480

知识点:  最小割

题目大意:

  求最小割并打印出最小割必须割掉的边。

解题思路:

  在跑完 \(sap\) 后的残量网络上,记录源点和汇点可达的点,然后遍历所有的边(设边的两端点为 \(u\) 和 \(v\)),如果 \(u\) 源点可达而 \(v\) 汇点可达(或与之相反,\(v\) 源点可达而 \(u\) 汇点可达),则说明该边必须割。

AC代码:

 #include <bits/stdc++.h>

 using namespace std;
const int MAXN=;
const int MAXM=;
const int INF=0x3f3f3f3f;
struct Edge{
int from,to,Next,cap,flow;
}edge[MAXM];
int flag[MAXN];
int tol;
int head[MAXN];
int gap[MAXN],dep[MAXN],cur[MAXN];
void init(){
tol=;
memset(flag,,sizeof(flag));
memset(head,-,sizeof(head));
}
void addedge(int u,int v,int w,int rw){
edge[tol].from=u; edge[tol].to=v; edge[tol].cap=w; edge[tol].flow=;
edge[tol].Next=head[u]; head[u]=tol++;
edge[tol].from=v; edge[tol].to=u; edge[tol].cap=rw; edge[tol].flow=;
edge[tol].Next=head[v]; head[v]=tol++;
}
int Q[MAXN];
void BFS(int start,int ends){
memset(dep,-,sizeof(dep));
memset(gap,,sizeof(gap));
gap[]=;
int fronts=,rear=;
dep[ends]=;
Q[rear++]=ends;
while(fronts!=rear){
int u=Q[fronts++];
for(int i=head[u];i!=-;i=edge[i].Next){
int v=edge[i].to;
if(dep[v]!=-) continue;
Q[rear++]=v;
dep[v]=dep[u]+;
gap[dep[v]]++;
}
}
}
int S[MAXN];
int sap(int start,int ends,int N){
BFS(start,ends);
memcpy(cur,head,sizeof(head));
int top=;
int u=start;
int ans=;
while(dep[start]<N){
if(u==ends){
int Min=INF;
int inser;
for(int i=;i<top;i++){
if(Min>edge[S[i]].cap-edge[S[i]].flow){
Min=edge[S[i]].cap-edge[S[i]].flow;
inser=i;
}
}
for(int i=;i<top;i++){
edge[S[i]].flow+=Min;
edge[S[i]^].flow-=Min;
}
ans+=Min;
top=inser;
u=edge[S[top]^].to;
continue;
}
bool flag=false;
int v;
for(int i=cur[u];i!=-;i=edge[i].Next){
v=edge[i].to;
if(edge[i].cap-edge[i].flow&&dep[v]+==dep[u]){
flag=true;
cur[u]=i;
break;
}
}
if(flag){
S[top++]=cur[u];
u=v;
continue;
}
int Min=N;
for(int i=head[u];i!=-;i=edge[i].Next){
if(edge[i].cap-edge[i].flow&&dep[edge[i].to]<Min){
Min=dep[edge[i].to];
cur[u]=i;
}
}
gap[dep[u]]--;
if(!gap[dep[u]]) return ans;
dep[u]=Min+;
gap[dep[u]]++;
if(u!=start) u=edge[S[--top]^].to;
}
return ans;
}
void dfs(int x,int od){
flag[x]=od;
for(int i=head[x];i!=-;i=edge[i].Next){
if(edge[i].flow==edge[i].cap) continue;
if(!flag[edge[i].to])
dfs(edge[i].to,od);
}
}
int main(){
// freopen("in.txt","r",stdin);
// freopen("out.txt","w",stdout);
int n,m;
while(scanf("%d%d",&n,&m)==&&n){
init();
int u,v,w;
for(int i=;i<m;i++){
scanf("%d%d%d",&u,&v,&w);
addedge(u,v,w,w);
}
sap(,,n);
dfs(,);
dfs(,);
for(int i=;i<tol;i+=){
int u=edge[i].from,v=edge[i].to;
if((flag[u]==&&flag[v]==)||(flag[u]==&&flag[v]==))
printf("%d %d\n",u,v);
}
printf("\n");
}
return ;
}

UVA10480 Sabotage的更多相关文章

  1. UVA10480:Sabotage(最小割+输出)

    Sabotage 题目链接:https://vjudge.net/problem/UVA-10480 Description: The regime of a small but wealthy di ...

  2. UVA10480 Sabotage —— 最小割最大流

    题目链接:https://vjudge.net/problem/UVA-10480 题解: 实际就是求最小割集. 1.什么是网络流图的“割”?答:一个边的集合,使得网络流图删除这些边之后,点被分成两部 ...

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

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

  4. USACO翻译:USACO 2014 MARCH GOLD P2 Sabotage

    1.破坏{DOLD题2} sabotage.pas/c/cpp [问题描述] 农夫约翰的头号敌人保罗决定破坏农民约翰的挤奶设备.挤奶设备排成一行,共N(3<= N <=100000)台挤奶 ...

  5. BZOJ 3477: [Usaco2014 Mar]Sabotage( 二分答案 )

    先二分答案m, 然后对于原序列 A[i] = A[i] - m,  然后O(n)找最大连续子序列和, 那么此时序列由 L + mx + R组成. L + mx + R = sum - n * m, s ...

  6. uva10480(最小割)

    传送门:Sabotage 题意:给定多个城市的网络,每个城市之间的通信有花费,要求使得首都和最大城市之间的通信断掉的最小花费.要求输出任意一组砸掉的边. 分析:跑一遍最大流dinic后,根据最小割定理 ...

  7. 洛谷2115 [USACO14MAR]破坏Sabotage

    https://www.luogu.org/problem/show?pid=2115 题目描述 Farmer John's arch-nemesis, Farmer Paul, has decide ...

  8. [USACO14MAR]破坏Sabotage 二分答案

    题目描述 Farmer John's arch-nemesis, Farmer Paul, has decided to sabotage Farmer John's milking equipmen ...

  9. 【二分 贪心】bzoj3477: [Usaco2014 Mar]Sabotage

    科学二分姿势 Description Farmer John's arch-nemesis, Farmer Paul, has decided to sabotage Farmer John's mi ...

随机推荐

  1. 【Linux常见命令】cp命令

    cp - copy files and directories 拷贝文件或目标文件夹,默认不能直接拷贝目录,通过-r参数设置递归复制目录 copy 语法: cp [OPTION]... [-T] SO ...

  2. optparse--强大的命令行参数处理包

    optparse,它功能强大,而且易于使用,可以方便地生成标准的.符合Unix/Posix 规范的命令行说明. optparse的简单示例: from optparse import OptionPa ...

  3. SpringBoot内置生命周期事件详解 SpringBoot源码(十)

    SpringBoot中文注释项目Github地址: https://github.com/yuanmabiji/spring-boot-2.1.0.RELEASE 本篇接 SpringBoot事件监听 ...

  4. 无法打开到SQL Server的连接 (Microsoft SQL Server, 错误:53) .

    标题: 连接到服务器 ------------------------------ 无法连接到 MSSQLSERVER. ------------------------------ 其他信息: 在与 ...

  5. mac OS 安装 Subversion JavaHL 客户端

    JavaHL原来官网  http://subclipse.tigris.org/wiki/JavaHL 目前已经全部转移到github 官方说明很详细 https://github.com/subcl ...

  6. Crash日志解析

    当应用程序崩溃时,会创建一个崩溃报告,这对于了解导致崩溃的原因非常有用.本文档包含有关如何表示,理解和解释崩溃报告的基本信息. 1.介绍 2.获取崩溃和低内存报告 3.象征性的奔溃报告 1.位码(bi ...

  7. Tomcat 8 Host-Manager配置访问的方法,全网唯一正确配置

    2019独角兽企业重金招聘Python工程师标准>>> 环境: 操作系统:         Linux version 2.6.32-696.10.1.el6.x86_64 (moc ...

  8. javascript中Function、ArrowFunction和GeneratorFunction介绍

    ECMAScript规范中对Function的文档描述,我认为是ECMAScript规范中最复杂也是最不好理解的一部分,它涉及到了各方面.光对Function就分了Function Definitio ...

  9. 【摘抄】深入解析Windows操作系统

    一.线程是一个进程内部的实体,也是Windows执行此进程时的调度实体.若没有线程,进程的程序将不可能运行.线程包含以下部件: 1.一组代表处理器状态的CPU寄存器中的内容. 2.两个栈:一个用于线程 ...

  10. 在for循环里面的++i与i++的区别

    ++i与i++在表面上没有什么区别 for(语句 1;语句 2;语句 3) 语句 1 在循环(代码块)开始前执行 语句 2 定义运行循环(代码块)的条件 语句 3 在循环(代码块)已被执行之后执行 ( ...