博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
POJ 3204 Ikki's Story I - Road Reconstruction
阅读量:4958 次
发布时间:2019-06-12

本文共 4538 字,大约阅读时间需要 15 分钟。

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

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 10 1 1

Sample Output

1

Source

, Ikki

题意:

给出一张有向图,求最小割的必须边的个数

分析:

最近学数学学的有点伤心...(智商被完虐...)所以我们还是来写萌萌哒的网络流...

怎样求最小割的必须边???考虑构成最小割集的边一定是满流的边,并且把这些边去掉之后S无法到达T,所以我们可以枚举满流边,判断这条边的两个点是否是属于不同的集合...需要注意的是一个点可能被一群满流边包围所以导致无法访问到,所以我们把属于S集合的点标为1,T集合的点标为2...需要注意的是bfs的时候一定是残留网络中的所有边而不是只有原图中的边...

代码:

1 #include
2 #include
3 #include
4 #include
5 #include
6 //by NeighThorn 7 #define inf 0x3f3f3f3f 8 using namespace std; 9 //大鹏一日同风起,扶摇直上九万里 10 11 const int maxn=500+5,maxm=5000*2+5;12 13 int n,m,ans,cnt,S,T,hd[maxn],to[maxm],fl[maxm],nxt[maxm],pos[maxn],vis[maxn];14 15 inline void add(int s,int x,int y){16 fl[cnt]=s;to[cnt]=y;nxt[cnt]=hd[x];hd[x]=cnt++;17 fl[cnt]=0;to[cnt]=x;nxt[cnt]=hd[y];hd[y]=cnt++;18 }19 20 inline bool bfs(void){21 memset(pos,-1,sizeof(pos));22 int head=0,tail=0,q[maxn];23 q[0]=S;pos[S]=0;24 while(head<=tail){25 int top=q[head++];26 for(int i=hd[top];i!=-1;i=nxt[i])27 if(pos[to[i]]==-1&&fl[i])28 pos[to[i]]=pos[top]+1,q[++tail]=to[i]; 29 }30 return pos[T]!=-1;31 }32 33 inline int find(int v,int f){34 if(v==T)35 return f;36 int res=0,t;37 for(int i=hd[v];i!=-1&&f>res;i=nxt[i])38 if(pos[to[i]]==pos[v]+1&&fl[i])39 t=find(to[i],min(fl[i],f-res)),fl[i]-=t,fl[i^1]+=t,res+=t;40 if(!res)41 pos[v]=-1;42 return res;43 }44 45 inline void dinic(void){46 while(bfs())47 while(find(S,inf));48 }49 50 inline void BFS(void){51 memset(vis,0,sizeof(vis));52 queue
q;q.push(S);vis[S]=1;53 while(!q.empty()){54 int top=q.front();q.pop();55 for(int i=hd[top];i!=-1;i=nxt[i])56 if(fl[i]&&!vis[to[i]])57 vis[to[i]]=1,q.push(to[i]);58 }59 q.push(T),vis[T]=2;60 while(!q.empty()){61 int top=q.front();q.pop();62 for(int i=hd[top];i!=-1;i=nxt[i])63 if(fl[i^1]&&!vis[to[i]])64 vis[to[i]]=2,q.push(to[i]);65 }66 }67 68 signed main(void){69 memset(hd,-1,sizeof(hd));70 memset(pos,-1,sizeof(pos));71 scanf("%d%d",&n,&m);ans=cnt=0;72 for(int i=1,s,x,y;i<=m;i++)73 scanf("%d%d%d",&x,&y,&s),x++,y++,add(s,x,y);74 S=1,T=n;dinic();BFS();75 for(int i=1;i<=n;i++)76 for(int j=hd[i];j!=-1;j=nxt[j])77 if((j&1)==0&&!fl[j])78 ans+=((vis[i]==vis[S]&&vis[to[j]]==vis[T])?1:0);79 printf("%d\n",ans);80 return 0;81 }//Cap ou pas cap. Cap.
View Code

By NeighThorn

 

转载于:https://www.cnblogs.com/neighthorn/p/6226703.html

你可能感兴趣的文章
sscanf在字符串中的一些使用
查看>>
[转]new一个Object对象占用多少内存?
查看>>
一步步教你Hadoop多节点集群安装配置
查看>>
JS_轮播案例
查看>>
【转】STM32 - 程序跳转、中断、开关总中断
查看>>
== & ===
查看>>
详解C#中的反射
查看>>
给java初学发者的一些建议,并对自身一年做一个总结。
查看>>
Android开发:Android虚拟机启动错误Can't find 'Linux version ' string in kernel image file
查看>>
2016.03.20
查看>>
href=#与href=javascriptvoid(0)的区别
查看>>
String 转化成java.sql.Date和java.sql.Time
查看>>
探寻读取文件的最快方法
查看>>
转:Eclipse中安装配置VSS
查看>>
[转]async & await 的前世今生(Updated)
查看>>
PostgreSQL本地化
查看>>
F: CET-4
查看>>
菜鸟对APP界面设计的一些心得小结
查看>>
nyoj 1208——水题系列——————【dp】
查看>>
ssh
查看>>