题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4240
思路:题意真的有点难理解:在城市A->B之间通过所有路径一小时之内能通过最大的车辆(Maxflow)/所有边上通过最大车流量(cap)的那条叫做redundancy ratio。最小的redundancy ratio是前者最大的车流量的那一条(cap),问minimum redundancy ratio是多少。
其实就是跑一次最大流,每当找到一条增广路时,记录此时的cap,然后取最大的就行了。
![](https://i-blog.csdnimg.cn/blog_migrate/8f900a89c6347c561fdf2122f13be562.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/961ddebeb323a10fe0623af514929fc1.gif)
1 #include<iostream> 2 #include<cstdio> 3 #include<cstring> 4 #include<algorithm> 5 #include<queue> 6 using namespace std; 7 #define MAXN 1111 8 #define inf 1<<30 9 10 struct Edge{ 11 int v,cap,next; 12 }edge[MAXN*MAXN]; 13 14 int n,m,vs,vt,NE,NV,MAX; 15 int head[MAXN]; 16 17 void Insert(int u,int v,int cap) 18 { 19 edge[NE].v=v; 20 edge[NE].cap=cap; 21 edge[NE].next=head[u]; 22 head[u]=NE++; 23 24 edge[NE].v=u; 25 edge[NE].cap=0; 26 edge[NE].next=head[v]; 27 head[v]=NE++; 28 } 29 30 int level[MAXN],gap[MAXN]; 31 void bfs(int vt) 32 { 33 memset(level,-1,sizeof(level)); 34 memset(gap,0,sizeof(gap)); 35 level[vt]=0; 36 gap[0]++; 37 queue<int>que; 38 que.push(vt); 39 while(!que.empty()){ 40 int u=que.front(); 41 que.pop(); 42 for(int i=head[u];i!=-1;i=edge[i].next){ 43 int v=edge[i].v; 44 if(level[v]!=-1)continue; 45 level[v]=level[u]+1; 46 gap[level[v]]++; 47 que.push(v); 48 } 49 } 50 } 51 52 int pre[MAXN],cur[MAXN]; 53 int SAP(int vs,int vt) 54 { 55 bfs(vt); 56 memset(pre,-1,sizeof(pre)); 57 memcpy(cur,head,sizeof(head)); 58 int u=pre[vs]=vs,aug=inf,maxflow=0; 59 gap[0]=NV; 60 while(level[vs]<NV){ 61 bool flag=false; 62 for(int &i=cur[u];i!=-1;i=edge[i].next){ 63 int v=edge[i].v; 64 if(edge[i].cap>0&&level[u]==level[v]+1){ 65 flag=true; 66 aug=min(aug,edge[i].cap); 67 pre[v]=u; 68 u=v; 69 if(v==vt){ 70 maxflow+=aug; 71 MAX=max(MAX,aug); 72 for(u=pre[u];v!=vs;v=u,u=pre[u]){ 73 edge[cur[u]].cap-=aug; 74 edge[cur[u]^1].cap+=aug; 75 } 76 aug=inf; 77 } 78 break; 79 } 80 } 81 if(flag)continue; 82 int minlevel=NV; 83 for(int i=head[u];i!=-1;i=edge[i].next){ 84 int v=edge[i].v; 85 if(edge[i].cap>0&&level[v]<minlevel){ 86 minlevel=level[v]; 87 cur[u]=i; 88 } 89 } 90 if(--gap[level[u]]==0)break; 91 level[u]=minlevel+1; 92 gap[level[u]]++; 93 u=pre[u]; 94 } 95 return maxflow; 96 } 97 98 int main() 99 { 100 int _case,t,u,v,cap; 101 scanf("%d",&_case); 102 while(_case--){ 103 scanf("%d%d%d%d%d",&t,&n,&m,&vs,&vt); 104 NE=0; 105 memset(head,-1,sizeof(head)); 106 NV=n; 107 MAX=0; 108 while(m--){ 109 scanf("%d%d%d",&u,&v,&cap); 110 Insert(u,v,cap); 111 } 112 printf("%d %.3lf\n",t,SAP(vs,vt)*1.0/MAX); 113 } 114 return 0; 115 } 116 117 118 119 120 121 122 123 124 125 126