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. 关于tp5自动过滤index.php

    在public/.htaccess 中输入这段代码即可实现过滤index.php <IfModule mod_rewrite.c> Options +FollowSymlinks -Mul ...

  2. C# 操作符 << 与 >>

    1.<< 左移操作符: 左移操作符,将第一个操作数向左移动第二个操作数指定的位数,空出的位置补0.左移相当于乘. 左移一位相当于乘2;左移两位相当于乘4;左移三位相当于乘8. 如:x< ...

  3. java并发编程目录

    java并发编程目录 Java多线程基础:进程和线程之由来 JAVA多线程实现的四种方式 Java并发编程:线程间协作的两种方式:wait.notify.notifyAll和Condition Jav ...

  4. ELK+Beats日志分析系统部署

    一.            名词介绍: E:ElasticSearch 搜索,简称es L:Logstash 管理日志和事件的工具 K:Kibana 功能强大的数据显示客户端 Beats 轻量级数据传 ...

  5. mezzanine的page_menu tag(二)

    dict的特性,key可以是None >>> def f(): a=[2,3] return a #函数返回local变量 >>> a=f() >>&g ...

  6. 深度学习原理与框架-Tensorflow卷积神经网络-cifar10图片分类(代码) 1.tf.nn.lrn(局部响应归一化操作) 2.random.sample(在列表中随机选值) 3.tf.one_hot(对标签进行one_hot编码)

    1.tf.nn.lrn(pool_h1, 4, bias=1.0, alpha=0.001/9.0, beta=0.75) # 局部响应归一化,使用相同位置的前后的filter进行响应归一化操作 参数 ...

  7. tmp32dll\sha1-586.asm(1432) : error A2070:invalid instruction operands 编译openssl出错

    vs命令行工具编译openssl最新版本的时候报perl版本太低. 后来换了openssl 1.0.2的版本旧版本到是可以正常编译了,但是1.0.2应该是版本还是优点新. 编译的时候报了下面的错误: ...

  8. C#调用java代码(IKVMC)

    参考资料:https://blog.csdn.net/threadroc/article/details/51406587 参考1:http://www.cnblogs.com/Jack-Blog/p ...

  9. LevelDB源码分析-编码

    编码(util/coding.h util/coding.cc) LevelDB将整型编码为二进制字符串的形式,同时又能够和ASCII字符区分. 首先是定长编码: void EncodeFixed32 ...

  10. html转换pdf

    项目需求:移动端APP项目需要在手机上签订合同,将html转换成pdf格式的文件 解决方案:是用插件wkhtmltopdf; 记录用法:1.网址https://wkhtmltopdf.org/ 下载压 ...