显然可以在实数域内二分答案
m
i
d
mid
mid,然后就变成所有边容量为
m
i
n
(
c
,
m
i
d
)
min(c,mid)
min(c,mid)的情况下最大流是否不变
直接
d
i
n
i
c
dinic
dinic似乎就可以了,精度要求不高
代码
#include<bits/stdc++.h>#define double long double#define eps 1e-6#define N 110usingnamespace std;template<typename node>voidchkmax(node &x, node y){x =max(x, y);}template<typename node>voidchkmin(node &x, node y){x =min(x, y);}template<typename node>voidread(node &x){
x =0;int f =1;char c =getchar();while(!isdigit(c)){if(c =='-') f =-1; c =getchar();}while(isdigit(c)) x = x *10+ c -'0', c =getchar(); x *= f;}struct Node {int x, y, c;} a[N *10];struct Edge {int next, num;double c;} e[N * N *5];int n, m, p, cnt, l[N], cur[N];voidadd(int x,int y,double c){
e[++cnt]=(Edge){e[x].next, y, c};
e[x].next = cnt;}voidAdd(int x,int y,double c){add(x, y, c),add(y, x,0);}boolbfs(){for(int i =2; i <= n; i++) l[i]=-1;
queue <int> q; q.push(1);while(!q.empty()){int x = q.front(); q.pop();for(int p = e[x].next; p; p = e[p].next){int k = e[p].num;double c = e[p].c;if(c > eps && l[k]==-1)
l[k]= l[x]+1, q.push(k);}}return l[n]!=-1;}doubledfs(int x,double lim){if(x == n)return lim;double used =0;for(int p = cur[x]; p; p = e[p].next){int k = e[p].num;double c = e[p].c;if(c > eps && l[k]== l[x]+1){double w =dfs(k,min(lim - used, c));
e[p].c -= w, e[p ^1].c += w, used += w;if(e[p].c > eps) cur[x]= p;if(lim - used < eps)return lim;}}if(used < eps) l[x]=-1;return used;}doubledinic(){double ret =0;while(bfs()){for(int i =1; i <= n; i++) cur[i]= e[i].next;
ret +=dfs(1, INT_MAX);}return ret;}boolcheck(double mid,double tmp){
cnt = n +(n %2==0);for(int i =1; i <= n; i++) e[i].next =0;for(int i =1; i <= m; i++){int x = a[i].x, y = a[i].y;double c = a[i].c;if(mid > c)Add(x, y, c);elseAdd(x, y, mid);}return tmp -dinic()< eps;}intmain(){read(n),read(m),read(p); cnt = n +(n %2==0);for(int i =1; i <= m; i++){read(a[i].x),read(a[i].y),read(a[i].c);Add(a[i].x, a[i].y, a[i].c);}double tmp =dinic(); cout << tmp <<"\n";double l =0, r = tmp;while(l + eps < r){double mid =(l + r)/2;if(check(mid, tmp)) r = mid;else l = mid;}
cout << fixed <<setprecision(6)<< r * p <<"\n";return0;}