题意很别扭的的一道题,先是求最大流,再求所有可行流中的流量最大的那个流(因为该流的流量取决于该流上流量最小的那条边,正好是题意要求的),然后求其比值即可
而dinic在dfs到汇点的时候正好也可以求出上述的流大小
#include<stdio.h>
#include<string.h>
#include<algorithm>
#include<queue>
#include<iostream>
using namespace std;
const int N = 100005;
const int inf = 99999999;
struct node{
int v, w, nxt;
}e[N*10];
int head[N], dep[N];
int cnt, n, m, ed, st;
int maxflow;
queue<int> q;
void init()
{
cnt = 0;
memset( head, -1, sizeof( head ));
maxflow = -1;
}
void add( int u, int v, int w )
{
e[cnt].v = v;
e[cnt].w = w;
e[cnt].nxt = head[u];
head[u] = cnt++;
e[cnt].v = u;
e[cnt].w = 0;
e[cnt].nxt = head[v];
head[v] = cnt++;
}
int bfs()
{
while( !q.empty() )
q.pop();
memset( dep, 0, sizeof( dep ));
dep[st] = 1;
q.push(st);
while( !q.empty() )
{
int u = q.front();
q.pop();
if( u == ed )
return 1;
for( int i = head[u]; ~i; i = e[i].nxt )
{
int v = e[i].v;
if( e[i].w && !dep[v] )
{
dep[v] = dep[u] + 1;
q.push(v);
}
}
}
return 0;
}
int dinic( int u, int minflow )
{
if( u == ed )
{
maxflow = max( maxflow, minflow);
return minflow;
}
int tmp = 0;
for( int i = head[u]; ~i; i = e[i].nxt )
{
int v = e[i].v;
if( e[i].w && dep[v] == dep[u] + 1 )
{
int flow = dinic( v, min(minflow - tmp, e[i].w));
e[i].w -= flow;
e[i^1].w += flow;
tmp += flow;
if( tmp == minflow )
return tmp;
}
}
return tmp;
}
int main()
{
int tot;
scanf("%d", &tot);
int dat;
while( tot-- )
{
scanf("%d%d%d%d%d", &dat, &n, &m, &st, &ed);
init();
int u, v, w;
while(m--)
{
scanf("%d%d%d", &u, &v, &w);
add(u, v, w);
}
int ans = 0, tmp;
maxflow = 0;
while( bfs() )
{
tmp = dinic(st, inf);
ans += tmp;
}
printf("%d %.3f\n", dat, (double)ans * 1.0 / (double) maxflow);
}
return 0;
}