ZOJ 2532 Internship(最大流找关键割边)
Description
CIA headquarter collects data from across the country through its classified network. They have been using optical fibres long before it's been deployed on any civilian projects. However they are still under a lot pressure recently because the data are growing rapidly. As a result they are considering upgrading the network with new technologies that provide a few times wider bandwidth. In the experiemental stage, they would like to upgrade one segment of their original network in order to see how it performs. And as a CIA intern it's your responsibility to investigate which segment could actually help increase the total bandwidth the headquarter receives, suppose that all the cities have infinite data to send and the routing algorithm is optimized. As they have prepared the data for you in a few minutes, you are told that they need the result immediately. Well, practically immediately.
Input
Input contains multiple test cases. First line of each test case contains three integers n, m and l, they represent the number of cities, the number of relay stations and the number of segments. Cities will be referred to as integers from 1 to n, while relay stations use integers from n+1 to n+m. You can saves assume that n + m <= 100, l <= 1000 (all of them are positive). The headquarter is identified by the integer 0.
The next l lines hold a segment on each line in the form of a b c, where a is the source node and b is the target node, while c is its bandwidth. They are all integers where a and b are valid identifiers (from 0 to n+m). c is positive. For some reason the data links are all directional.
The input is terminated by a test case with n = 0. You can safely assume that your calculation can be housed within 32-bit integers.
Output
For each test print the segment id's that meets the criteria. The result is printed in a single line and sorted in ascending order, with a single space as the separator. If none of the segment meets the criteria, just print an empty line. The segment id is 1 based not 0 based.
题目大意:有n个发射点,m个中间点,和一个接受点0,中间由L条有向光纤连接,每个光纤有一定的带宽,问扩大哪些光纤(只能扩大一条)的带宽可以扩大发射点的总带宽。
思路:从源点S到n个发射点连一条容量为无穷大的边,再连接L条光纤,容量为该光纤的带宽,以0为汇点T。题目转化成扩大哪些边的容量可以增加最大流。先在图上求最大流,在残量网络中,把S能到的点标记为1,把能到T的点标记为2,那么当一条边的出发点为1、结束点为2,这条边就是关键割边,也就是所求的边之一。如果有一条边的其中一个点未被标记,那么扩大这条边的容量,也就不过是从源点到达的点多了一个,或者到达汇点的点多了一个,但是在这个残量网络中依旧没有从S到T的增广路。如果两个点都未被标记……那更加不可以啦……
PS:出发点为2结束点为1的边,增加容量也不会有增广路出现,曾因为这个WA了一次>_<
BFS+ISAP(30MS):
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <queue>
using namespace std; const int MAXN = ;
const int MAXE = ;
const int INF = 0x3fff3fff; struct SAP {
int head[MAXN], dis[MAXN], pre[MAXN], cur[MAXN], gap[MAXN];
int to[MAXE], next[MAXE], flow[MAXE];
int n, st, ed, ecnt; void init() {
memset(head, , sizeof(head));
ecnt = ;
} void add_edge(int u, int v, int c) {
to[ecnt] = v; flow[ecnt] = c; next[ecnt] = head[u]; head[u] = ecnt++;
to[ecnt] = u; flow[ecnt] = ; next[ecnt] = head[v]; head[v] = ecnt++;
//printf("%d->%d flow = %d\n", u, v, c);
} void bfs() {
memset(dis, 0x3f, sizeof(dis));
queue<int> que; que.push(ed);
dis[ed] = ;
while(!que.empty()) {
int u = que.front(); que.pop();
++gap[dis[u]];
for(int p = head[u]; p; p = next[p]) {
int &v = to[p];
if(flow[p ^ ] && dis[v] > n) {
dis[v] = dis[u] + ;
que.push(v);
}
}
}
} int Max_flow(int ss, int tt, int nn) {
st = ss; ed = tt; n = nn;
int ans = , minFlow = INF, u;
for(int i = ; i <= n; ++i) {
cur[i] = head[i];
gap[i] = ;
}
u = pre[st] = st;
bfs();
while(dis[st] < n) {
bool flag = false;
for(int &p = cur[u]; p; p = next[p]) {
int &v = to[p];
if(flow[p] && dis[u] == dis[v] + ) {
flag = true;
minFlow = min(minFlow, flow[p]);
pre[v] = u;
u = v;
if(u == ed) {
ans += minFlow;
while(u != st) {
u = pre[u];
flow[cur[u]] -= minFlow;
flow[cur[u] ^ ] += minFlow;
}
minFlow = INF;
}
break;
}
}
if(flag) continue;
int minDis = n - ;
for(int p = head[u]; p; p = next[p]) {
int &v = to[p];
if(flow[p] && minDis > dis[v]) {
minDis = dis[v];
cur[u] = p;
}
}
if(--gap[dis[u]] == ) break;
gap[dis[u] = minDis + ]++;
u = pre[u];
}
return ans;
} int mark[MAXN]; void make_cut() {
memset(mark, , sizeof(mark));
queue<int> que;
que.push(st); mark[st] = ;
while(!que.empty()) {
int u = que.front(); que.pop();
for(int p = head[u]; p; p = next[p]) {
int &v = to[p];
if(flow[p] && !mark[v]) {
mark[v] = ;
que.push(v);
}
}
}
que.push(ed); mark[ed] = ;
while(!que.empty()) {
int u = que.front(); que.pop();
for(int p = head[u]; p; p = next[p]) {
int &v = to[p];
if(flow[p ^ ] && !mark[v]) {
mark[v] = ;
que.push(v);
}
}
}
}
} G; int from[MAXE], to[MAXE];
int n, m, L, c; int main() {
while(scanf("%d%d%d", &n, &m, &L) != EOF) {
if(n == ) break;
int ss = n + m + , tt = ;
G.init();
for(int i = ; i <= n; ++i) G.add_edge(ss, i, INF);
for(int i = ; i <= L; ++i) {
scanf("%d%d%d", &from[i], &to[i], &c);
G.add_edge(from[i], to[i], c);
}
//printf("%d\n", G.Max_flow(ss, tt, ss));
G.Max_flow(ss, tt, ss);
G.make_cut();
bool flag = false;
for(int i = ; i <= L; ++i) {
int &u = from[i], &v = to[i];
if(G.mark[u] == && G.mark[v] == ) {
if(flag) printf(" ");
printf("%d", i);
flag = true;
}
}
puts("");
}
}
ZOJ 2532 Internship(最大流找关键割边)的更多相关文章
- ZOJ 2532 Internship 求隔边
Internship Time Limit: 5 Seconds Memory Limit: 32768 KB CIA headquarter collects data from acro ...
- zoj 2532 Internship【最小割】
就是求哪些边在最大流上满流,也就是找割边.把0作为t点,s向所有的1~n连流量为inf的边,其他的边按照流量连.跑一遍最大流,从s顺着有残余流量的正向边dfs打标记fr,从t顺着正向边有残余流量的反向 ...
- ZOJ 2532 Internship
Internship Time Limit: 5000ms Memory Limit: 32768KB This problem will be judged on ZJU. Original ID: ...
- B - Internship (网络流关键割边)
题目链接:https://cn.vjudge.net/contest/281961#problem/B 题目大意:给你n个城市,中间有一些中转站,然后给你终点,再给你l条轨道以及流量,问你增加哪几条轨 ...
- poj 3204(最小割--关键割边)
Ikki's Story I - Road Reconstruction Time Limit: 2000MS Memory Limit: 131072K Total Submissions: 7 ...
- POJ3204 Ikki's Story - Road Reconstruction 网络流图的关键割边
题目大意:一个有源有汇的城市,问最少增加城市中的多少道路可以增加源到汇上各个路径上可容纳的总车流量增加. 网络流关键割边集合指如果该边的容量增加,整个网络流图中的任意从原点到汇点的路径的流量便可增加. ...
- hdu3313 最大流找关键点,或者最短路找关键点.
题意: 给你一个有向图,然后给你起点和终点,问你从起点到终点有多少个关键点,如果当前的这个点删除了就无法从起点到终点,那么这个点就是一个关键点.. 思路: (1)有两种做法,我用的 ...
- hdu 4975 A simple Gaussian elimination problem 最大流+找环
原题链接 http://acm.hdu.edu.cn/showproblem.php?pid=4975 这是一道很裸的最大流,将每个点(i,j)看作是从Ri向Cj的一条容量为9的边,从源点除法连接每个 ...
- HDU-3416 Marriage Match IV 最短路+最大流 找各最短路的所有边
题目链接:https://cn.vjudge.net/problem/HDU-3416 题意 给一个图,求AB间最短路的条数(每一条最短路没有重边.可有重复节点) 思路 首先把全部最短路的边找出来,再 ...
随机推荐
- MySQL至TiDB复制延迟监控
因生产环境mysql中有较多复杂sql且运行效率低,因此采用tidb作为生产环境的从库进行部分慢sql及报表的读写分离.其中MySQL至TIDB采用Syncer工具同步.关于TIDB的安装及Synce ...
- Apache 错误:httpd: Could not open configuration file
神奇的事件,折磨我 电脑关机重启了一下关机之前正常的状态没有任何的异常出现,过了一会开机准备工作.神奇的事情tmd出现了!!!! 打开phpstudy 启动... 嗯?apache亮红报错?? 第一反 ...
- FireDAC的SQLite初探
// uses FireDAC.VCLUI.Wait 之后, 可不用添加 TFDGUIxWaitCursor TFDConnection // 数据连接 TFDQuery ...
- Django模板语言与视图(view)
常用语法 {{ }}和{% %} 变量相关的用{{}} , 逻辑相关的用{% %} 变量 在Django的模板语言中按此语法使用:{{ 变量名 }}. 当模版引擎遇到一个变量,它将计算这个变量,然后 ...
- 解决 Node.js 错误 Error:listen EADDRINUSE
第一次尝试 node.js 中的 express 框架,写了第一个 js 文件之后,在 WebStorm 运行,到游览器刷新,成功运行. 又创建一个 js 文件,写的是静态路由的访问,结果出现了 Er ...
- (数据科学学习手札42)folium进阶内容介绍
一.简介 在上一篇(数据科学学习手札41)中我们了解了folium的基础内容,实际上folium在地理信息可视化上的真正过人之处在于其绘制图像的高度可定制化上,本文就将基于folium官方文档中的一些 ...
- R语言爬虫:CSS方法与XPath方法对比(表格介绍)
css 选择器与 xpath 用法对比 目标 匹配节点 CSS 3 XPath 所有节点 ~ * //* 查找一级.二级.三级标题节点 <h1>,<h2>,<h3> ...
- JDK核心源码(2)
Java的基础知识有很多,但是我认为最基础的知识应该要属jdk的基础代码, jdk的基础代码里面,有分了很多基础模块,其中又属jdk包下面的lang包最为基础. 我们下面将总结和分析一下lang包下面 ...
- 友晶Altera Cyclone V GX Starter Kit开发板使用ADC-第一篇
1. 拿到板子在,做工很好,属于GX系列,GX应该是高速收发器 2. 去探究下GX是什么用途,大约有6个型号,这个板子是5CGXFX5,有77 LE逻辑单元,这个收发器不知道是什么?6个 3.125G ...
- oracle分区表按时间自动创建
表分区是一种思想,分区表示一种技术实现.当表的大小过G的时候可以考虑进行表分区,提高查询效率,均衡IO.oracle分区表是oracle数据库提供的一种表分区的实现形式.表进行分区后,逻辑上仍然是一张 ...