POJ3204 Ikki's Story I
来源:互联网 发布:mfp126a 有网络口吗 编辑:程序博客网 时间:2024/06/02 07:16
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 N, M (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 a, b, c, which means that there is a road from city a to city b with a transportation capacity of c (0 ≤ a, b < n, c ≤ 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
Sample Input
2 10 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 longconst int INF = 0x3f3f3f3f;#define MAXN 800struct 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
- POJ3204-Ikki's Story I
- poj3204 Ikki's Story I - Road Reconstruction
- POJ3204 Ikki's Story I - Road Reconstruction
- POJ3204——Ikki's Story I
- POJ3204 Ikki's Story I - Road Reconstruction [最大流]
- POJ3204( Ikki's Story I - Road Reconstruction)
- poj3204 Ikki's Story I - Road Reconstruction 网络流dinic
- 【poj3204】Ikki's Story I - Road Reconstruction 最小割必须边
- POJ 3204 Ikki's Story I - Road Reconstruction
- poj 3204 Ikki's Story I - Road Reconstruction(最大流割边)
- poj 3204 Ikki's Story I - Road Reconstruction
- POJ 3204 Ikki's Story I - Road Reconstruction (求割边)
- poj 3204 Ikki's Story I - Road Reconstruction
- POJ-3204-Ikki's Story I - Road Reconstruction
- POJ 3204 Ikki's Story I | 最小割
- 【POJ】3204 Ikki's Story I - Road Reconstruction 最大流
- poj 3204 Ikki's Story I - Road Reconstruction 最大流
- 以太坊中的Gas以及其设计原理
- C++笔记@(2)
- Glide入门教程
- java反射系列01 getName()的实现
- Linux/Android系统知识之repo git知识篇
- POJ3204 Ikki's Story I
- typescript 学习 文档 手册
- asp.net大文件分块上传视频教程
- 二分查找算法递归实现&&快速排序算法实现
- 分支管理策略
- (40)异常、多态、|与||的分析结果题目
- 8.ThinkPHP 3.1.2 查询方式的一般使用1
- 闭包算法
- linux修改权限