题目链接:https://cn.vjudge.net/contest/281961#problem/B

题目大意:给你n个城市,中间有一些中转站,然后给你终点,再给你l条轨道以及流量,问你增加哪几条轨道的流量可以使得流到终点的流量增加。

具体思路:首先分析一波,一开始想的是找割边,但是只是找出割边是不可以的。举个例子 : s->u->t,这样的话,假设这两条边都是满流,都可以当做割边,但是如果只是增加割边的流量的话,会受到其他边的流量的限制,最终流量还是不会增加的,所以,换一个思路,我们先跑一遍最大流,然后观察残余网络的情况,如果一条边的起点和终点对应的起点作为另一条边的终点以及终点对应另一条边的起点的话,依旧是如果增加当前这条边的流量的话,还是可以增加流量的,这样关键割边就找出来了。

AC代码:

 #include<iostream>
#include<stack>
#include<queue>
#include<iomanip>
#include<stdio.h>
#include<cstring>
#include<cstring>
#include<cmath>
#include<algorithm>
#include<map>
#include<vector>
using namespace std;
# define ll long long
const int maxn = 4e3+;
# define inf 0x3f3f3f3f
int st,ed;
int prev[maxn];
int head[maxn];
int line[maxn];
int vis1[maxn],vis2[maxn];
struct node
{
int fr;
int to;
int flow;
int nex;
} edge[maxn];
int num;
void init()
{
memset(head,-,sizeof(head));
memset(vis1,,sizeof(vis1));
memset(vis2,,sizeof(vis2));
num=;
}
void addedge(int fr,int to,int flow)
{
edge[num].to=to;
edge[num].fr=fr;
edge[num].flow=flow;
edge[num].nex=head[fr];
head[fr]=num++;
edge[num].to=fr;
edge[num].fr=to;
edge[num].flow=;
edge[num].nex=head[to];
head[to]=num++;
}
bool bfs()
{
memset(prev,-,sizeof(prev));
prev[st]=;
queue<int>q;
q.push(st);
while(!q.empty())
{
int top=q.front();
q.pop();
for(int i=head[top]; i!=-; i=edge[i].nex)
{
int temp=edge[i].to;
if(prev[temp]==-&&edge[i].flow>)
{
prev[temp]=prev[top]+;
q.push(temp);
}
}
}
return prev[ed]!=-;
}
int dfs(int u,int flow)
{
if(u==ed)
return flow;
int res=;
for(int i=head[u]; i!=-; i=edge[i].nex)
{
int t=edge[i].to;
if(prev[t]==(prev[u]+)&&edge[i].flow>)
{
int temp=dfs(t,min(flow,edge[i].flow));
edge[i].flow-=temp;
edge[i^].flow+=temp;
res+=temp;
flow-=temp;
if(flow==)
break;
}
}
if(res==)
prev[u]=-;
return res;
}
void dinic()
{
int ans=;
while(bfs())
{
ans+=dfs(st,inf);
}
}
void dfs1(int u)
{
vis1[u]=;
for(int i=head[u]; i!=-; i=edge[i].nex)
{
int v=edge[i].to;
if(!vis1[v]&&edge[i].flow)
dfs1(v);
}
}
void dfs2(int u)
{
vis2[u]=;
for(int i=head[u]; i!=-; i=edge[i].nex)
{
int v=edge[i].to;
if(!vis2[v]&&edge[i^].flow)
{
dfs2(v);
}
}
}
int main()
{
int n,m,l;
while(~scanf("%d",&n))
{
if(n==)
break;
init();
scanf("%d %d",&m,&l);
st=n+m+;
ed=;
int t1,t2,t3;
for(int i=; i<l; i++)
{
scanf("%d %d %d",&t1,&t2,&t3);
line[i]=num;
addedge(t1,t2,t3);
}
for(int i=; i<=n; i++)
{
addedge(st,i,inf);
}
dinic();
dfs1(st);
dfs2(ed);
// cout<<1<<endl;
int flag=;
for(int i=; i<l; i++)
{
// cout<<i<<endl;
if(edge[line[i]].flow==&&vis1[edge[line[i]].fr]&&vis2[edge[line[i]].to])
{
// cout<<i<<endl;
if(flag)
{
printf("%d",i+);
flag=;
}
else
{
printf(" %d",i+);
}
}
}
printf("\n");
}
return ;
}

B - Internship (网络流关键割边)的更多相关文章

  1. POJ3204 Ikki's Story - Road Reconstruction 网络流图的关键割边

    题目大意:一个有源有汇的城市,问最少增加城市中的多少道路可以增加源到汇上各个路径上可容纳的总车流量增加. 网络流关键割边集合指如果该边的容量增加,整个网络流图中的任意从原点到汇点的路径的流量便可增加. ...

  2. ZOJ 2532 Internship(最大流找关键割边)

    Description CIA headquarter collects data from across the country through its classified network. Th ...

  3. poj 3204(最小割--关键割边)

    Ikki's Story I - Road Reconstruction Time Limit: 2000MS   Memory Limit: 131072K Total Submissions: 7 ...

  4. Internship-ZOJ2532(网络流求割边)

    Internship Time Limit: 5 Seconds      Memory Limit: 32768 KB CIA headquarter collects data from acro ...

  5. POJ 3204 Ikki's Story I-Road Reconstruction (网络流关键边)

    [题意]给定一个N个节点M条边的网络流,求有多少条边,使得当增其中加任何一个边的容量后,整个网络的流将增加. 挺好的一道题,考察对网络流和增广路的理解. [思路] 首先关键边一定是满流边.那么对于一个 ...

  6. Soj题目分类

    -----------------------------最优化问题------------------------------------- ----------------------常规动态规划 ...

  7. OI网络流 简单学习笔记

    持续更新! 基本上只是整理了一下框架,具体的学习给出了个人认为比较好的博客的链接. ..怎么说呢,最基础的模板我就我不说了吧qwq,具体可以参考一下这位大佬写的博客:最大流,最小割,费用流 费用流 跑 ...

  8. POJ 1486 Sorting Slides (二分图关键匹配边)

    题意 给你n个幻灯片,每个幻灯片有个数字编号1~n,现在给每个幻灯片用A~Z进行编号,在该幻灯片范围内的数字都可能是该幻灯片的数字编号.问有多少个幻灯片的数字和字母确定的. 思路 确定幻灯片的数字就是 ...

  9. ZOJ 2587 Unique Attack (最小割唯一性)

    题意 判断一个无向图的割是否唯一 思路 错误思路:一开始想的是判断割边是否都是关键割边,那既然割边两端点能连通S.T点的边是关键边,那么只要遇到有某个边两端点不连通S or T则这条边就不是关键割边( ...

随机推荐

  1. [代码]--C#action和func的使用

    以前我都是通过定义一个delegate来写委托的,但是最近看一些外国人写的源码都是用action和func方式来写,当时感觉对这很陌生所以看起源码也觉得陌生,所以我就花费时间来学习下这两种方式,然后发 ...

  2. php-编译模块2

    PHP扩展-扩展的生成和编译 首先说明一下,PHP扩展有两种编译方式:方式一:在编译PHP时直接将扩展编译进去方式二:扩展被编译成.so文件,在php.ini里配置加载路径: 以下开始说明创建PHP扩 ...

  3. BZOJ2733[HNOI2012]永无乡——线段树合并+并查集+启发式合并

    题目描述 永无乡包含 n 座岛,编号从 1 到 n,每座岛都有自己的独一无二的重要度,按照重要度可 以将这 n 座岛排名,名次用 1 到 n 来表示.某些岛之间由巨大的桥连接,通过桥可以从一个岛 到达 ...

  4. Uva101-STL模拟

    一道有点复杂的STL模拟题,对STL迭代器不太熟悉改了好久,最后总算A了出来. 感觉用数组更方便...但是为了练习STL嘛 对比白书上的代码,我写的还是傻了点.一开始没有理解四个操作的意思,单纯的模拟 ...

  5. QAU 18校赛 J题 天平(01背包 判断能否装满)

    问题 J: 天平 时间限制: 1 Sec  内存限制: 128 MB提交: 36  解决: 9[提交][状态][讨论版][命题人:admin] 题目描述 天平的右端放着一件重量为w的物品.现在有n个重 ...

  6. 自学Aruba1.3-WLAN厂家魔力象限

    点击返回:自学Aruba之路 自学Aruba1.3-WLAN厂家魔力象限 以下为2017<有线和无线局域网接入基础设施的魔力象限>报告:      Aruba.cisco为无线领域领导者. ...

  7. 【BZOJ3129】[SDOI2013]方程(容斥,拓展卢卡斯定理)

    [BZOJ3129][SDOI2013]方程(容斥,拓展卢卡斯定理) 题面 BZOJ 洛谷 题解 因为答案是正整数,所先给每个位置都放一个就行了,然后\(A\)都要减一. 大于的限制和没有的区别不大, ...

  8. virtualenv 包管理

    创建虚拟环境: 1) pip install virtualenv 2) virtualenv  DemoEnv(虚拟环境名) 3) 此处windows和linux不同系统下的文件结构略有不同 lin ...

  9. 使用React.cloneElement()给子组件传值

    React提供了一个克隆组件的API: React.cloneElement( element, [props], [...child] ) 可以利用该方法,给子组件传值,使用如下: class Pa ...

  10. ref实现输入框聚焦

    关于ref我们是怎么理解的呢? 我们可以通过React.createRef()创建一个 ref节点,并将其打印出来. 代码如下: import React,{Component} from 'reac ...