Ikki's Story I - Road Reconstruction
Time Limit: 2000MS   Memory Limit: 131072K
Total Submissions: 7971   Accepted: 2294

Description

Ikki is the king of a small country – Phoenix, Phoenix is so small that there is only one city that is responsible for the production of daily goods, and uses the road network to transport the goods to the capital. Ikki finds that the biggest problem in the country is that transportation speed is too slow.

Since Ikki was an ACM/ICPC contestant before, he realized that this, indeed, is a maximum flow problem. He coded a maximum flow program and found the answer. Not satisfied with the current status of the transportation speed, he wants to increase the transportation ability of the nation. The method is relatively simple, Ikki will reconstruct some roads in this transportation network, to make those roads afford higher capacity in transportation. But unfortunately, the country of Phoenix is not so rich in GDP that there is only enough money to rebuild one road. Ikki wants to find such roads that if reconstructed, the total capacity of transportation will increase.

He thought this problem for a loooong time but cannot get it. So he gave this problem to frkstyc, who put it in this POJ Monthly contest for you to solve. Can you solve it for Ikki?

Input

The input contains exactly one test case.

The first line of the test case contains two integers NM (N ≤ 500, M ≤ 5,000) which represents the number of cities and roads in the country, Phoenix, respectively.

M lines follow, each line contains three integers abc, which means that there is a road from city a to city b with a transportation capacity of c (0 ≤ ab < nc ≤ 100). All the roads are directed.

Cities are numbered from 0 to n − 1, the city which can product goods is numbered 0, and the capital is numbered n − 1.

Output

You should output one line consisting of only one integer K, denoting that there are K roads, reconstructing each of which will increase the network transportation capacity.

Sample Input

2 1
0 1 1

Sample Output

1

————————————————————————————————

题目大意是这样,找这样一种边的个数,就是增加该边的容量,可以使得最大流变大

思路:就时最大流关键边的判定,首先我们跑一遍最大流。然后不能枚举每条边增大然后跑最大流,这样太慢。我们可以知道,关键便一定是满流的,而且从源点到它和它到汇点一定能找出增广路,所以我们先dfs找出源点和汇点能流到哪些点,然后枚举每条边判断是否满流且源点汇点均能达到

#include <iostream>
#include <cstdio>
#include <cstring>
#include <string>
#include <algorithm>
#include <cmath>
#include <map>
#include <set>
#include <stack>
#include <queue>
#include <vector>
#include <bitset> using namespace std; #define LL long long
const int INF = 0x3f3f3f3f;
#define MAXN 800 struct node
{
int u, v, next, cap;
} edge[MAXN*MAXN];
int nt[MAXN], s[MAXN], d[MAXN], visit[MAXN],vis[MAXN];
int a[MAXN],b[MAXN];
int cnt; void init()
{
cnt = 0;
memset(s, -1, sizeof(s));
} void add(int u, int v, int c)
{
edge[cnt].u = u;
edge[cnt].v = v;
edge[cnt].cap = c;
edge[cnt].next = s[u];
s[u] = cnt++;
edge[cnt].u = v;
edge[cnt].v = u;
edge[cnt].cap = 0;
edge[cnt].next = s[v];
s[v] = cnt++;
} bool BFS(int ss, int ee)
{
memset(d, 0, sizeof d);
d[ss] = 1;
queue<int>q;
q.push(ss);
while (!q.empty())
{
int pre = q.front();
q.pop();
for (int i = s[pre]; ~i; i = edge[i].next)
{
int v = edge[i].v;
if (edge[i].cap > 0 && !d[v])
{
d[v] = d[pre] + 1;
q.push(v);
}
}
}
return d[ee];
} int DFS(int x, int exp, int ee)
{
if (x == ee||!exp) return exp;
int temp,flow=0;
for (int i = nt[x]; ~i ; i = edge[i].next, nt[x] = i)
{
int v = edge[i].v;
if (d[v] == d[x] + 1&&(temp = (DFS(v, min(exp, edge[i].cap), ee))) > 0)
{
edge[i].cap -= temp;
edge[i ^ 1].cap += temp;
flow += temp;
exp -= temp;
if (!exp) break;
}
}
if (!flow) d[x] = 0;
return flow;
} int Dinic_flow(int ss,int ee)
{ int ans = 0;
while (BFS(ss, ee))
{
for (int i = 0; i <=ee; i++) nt[i] = s[i];
ans+= DFS(ss, INF, ee);
}
return ans;
} void dfs1(int n)
{ for(int i=s[n]; ~i; i=edge[i].next)
{
if(edge[i].cap>0&&!a[edge[i].v])
{
a[edge[i].v]=1;
vis[edge[i].v]=1;
dfs1(edge[i].v);
vis[edge[i].v]=0;
}
}
} void dfs2(int n)
{ for(int i=s[n]; ~i; i=edge[i].next)
{
if(edge[i^1].cap>0&&!b[edge[i].v])
{
b[edge[i].v]=1;
vis[edge[i].v]=1;
dfs2(edge[i].v);
vis[edge[i].v]=0;
}
}
} int main()
{
int n,m,u,v,c;
while(~scanf("%d%d",&n,&m))
{
init();
for(int i=0; i<m; i++)
{
scanf("%d%d%d",&u,&v,&c);
add(u,v,c);
}
int ans=Dinic_flow(0,n-1);
memset(a,0,sizeof a);
memset(b,0,sizeof b);
a[0]=1;
b[n-1]=1;
dfs1(0);
dfs2(n-1);
int k=0;
for(int i=0;i<cnt;i+=2)
{
if(edge[i].cap==0&&a[edge[i].u]==1&&b[edge[i].v]==1)
k++;
}
printf("%d\n",k);
}
return 0;
}

POJ3204 Ikki's Story I - Road Reconstruction的更多相关文章

  1. POJ 3204 Ikki's Story I - Road Reconstruction

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

  2. POJ3184 Ikki's Story I - Road Reconstruction(最大流)

    求一次最大流后,分别对所有满流的边的容量+1,然后看是否存在增广路. #include<cstdio> #include<cstring> #include<queue& ...

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

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

  4. POJ-3204-Ikki's Story I - Road Reconstruction(最大流)

    题意: 给一个有向图 求给那些边增加容量能增加总的流量,求边的条数 分析: 一开始求的是割边,结果wa了,那是因为有些割边增加了容量,但总的容量也不会增加 只有满流的边并且从源点汇点都有一条可扩展的路 ...

  5. poj3204Ikki's Story I - Road Reconstruction(最大流求割边)

    链接 最大流=最小割  这题是求割边集 dinic求出残余网络 两边dfs分别以源点d找到可达点 再以汇点进行d找到可达汇点的点 如果u,v为割边 那么s->u可达 v->t可达 并且为饱 ...

  6. [转] POJ图论入门

    最短路问题此类问题类型不多,变形较少 POJ 2449 Remmarguts' Date(中等)http://acm.pku.edu.cn/JudgeOnline/problem?id=2449题意: ...

  7. 【转载】图论 500题——主要为hdu/poj/zoj

    转自——http://blog.csdn.net/qwe20060514/article/details/8112550 =============================以下是最小生成树+并 ...

  8. Soj题目分类

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

  9. BUPT2017 wintertraining(15) #3 题解

    我觉得好多套路我都不会ヘ(;´Д`ヘ) 题解拖到情人节后一天才完成,还有三场没补完,真想打死自己.( ˙-˙ ) A - 温泉旅店 UESTC - 878  题意 ​ 有n张牌,两人都可以从中拿出任意 ...

随机推荐

  1. IDEA(MAC) 快捷键

    从eclipse到IDEA:从Windows到MAC 有些不习惯,记录一些日常使用的快捷键 1.格式化代码 command+alt+L 2.导包 alt+ enter 3.自动生成该类型的对象 com ...

  2. TensorFlow学习之二

    二.常用操作符和基本数学函数 大多数运算符都进行了重载操作,使我们可以快速使用 (+ - * /) 等,但是有一点不好的是使用重载操作符后就不能为每个操作命名了. 1  算术操作符:+ - * / % ...

  3. 阿里云ODPS <====>蚂蚁大数据

    1.命令行客户端工具的安装参考文档:http://repo.aliyun.com/odpscmd/?spm=a2c4g.11186623.2.17.5c185c23zHshCq 2.创建和查看表:ht ...

  4. 详细分析MySQL事务日志(redo log和undo log) 表明了为何mysql不会丢数据

    innodb事务日志包括redo log和undo log.redo log是重做日志,提供前滚操作,undo log是回滚日志,提供回滚操作. undo log不是redo log的逆向过程,其实它 ...

  5. Python代码的人机大战(循环嵌套)

    第一次动手写随笔,记录一下今早的1.5小时努力成果 题目是这样的 : 人和机器进行猜拳游戏写成一个类,首先选择角色:1 曹操 2张飞 3 刘备,然后选择的角色进行猜拳:1剪刀 2石头 3布 玩家输入一 ...

  6. VS2017安装步骤详解

    原文地址:https://www.ithome.com/html/win10/297093.htm 微软最近发布了正式版Visual Studio 2017并公开了其下载方式,不过由于VS2017采用 ...

  7. db2开启监控monitor 查看快照snapshot

    ths   https://blog.csdn.net/huaishu/article/details/9671771 #查看监控器 db2 get monitor switches #打开监控器db ...

  8. Failed to connect to /127.0.0.1:8080

    参考 https://blog.csdn.net/qq_36523667/article/details/78823065 127.0.0.1为虚拟机的地址,需要将地址改为本机实际地址  ipconf ...

  9. ExecuteReader()获得数据

    ExecuteReader用于实现只进只读的高效数据查询.ExecuteReader:返回一个SqlDataReader对象,可以通过这个对象来检查查询结果,它提供了只进只读的执行方式,即从结果中读取 ...

  10. 2018-2019-2 20175234 实验一 Java开发环境的熟悉(Linux + IDEA)

    目录 20175234 实验一 Java开发环境的熟悉(Linux + IDEA) 第一部分 代码及运行结果截图 第二部分 要求 代码及截图 第三部分 题目 需求分析 设计 程序及运行结果 问题和解决 ...