BZOJ 4501 旅行
题目大意 : http://www.lydsy.com/JudgeOnline/problem.php?id=4501
首先对于每一个节点,如果f[u] max , 那么每一个 v 都应取到相应的max,那么我们可以按拓扑序逆序(也就是dfs序的逆序) 先算出来每一个f[v],然后再考虑每一个节点的更新,按题意来说,
#include <bits/stdc++.h>
using namespace std;
const double eps = 1e-7;
const int MAXN = 50005,MAXM = 500005,S = 0,T = 5001,inf = 0x7fffffff;
bool vis[MAXN];
int n,m,k; double f[MAXN];
vector<int>G[MAXN];
template<typename _t>
inline _t read(){
_t x=0,f=1;
char ch=getchar();
for(;ch>'9'||ch<'0';ch=getchar())if(ch=='-')f=-f;
for(;ch>='0'&&ch<='9';ch=getchar())x=x*10+(ch^48);
return x*f;
}
struct Max_flow{
int first[MAXN],e,d[MAXN],Q[MAXN];
Max_flow(){clear();}
struct edge{
int u,v,next,id;double w;
}a[MAXM];
inline void clear(){
memset(first,0,sizeof first); e = 2;
}
inline void add(int u,int v,int w){
a[e].u = u;a[e].v = v;a[e].id = w;
a[e].next = first[u];first[u] = e++;
}
inline void add(int u,int v,double w){
a[e].u = u;a[e].v = v;a[e].w = w;
a[e].next = first[u];first[u] = e++;
}
inline void push(int u,int v,double w){
add(u,v,w);add(v,u,0.0);
}
inline bool bfs(){
memset(d,-1,sizeof d); d[S] = 0;
int l = 0,r = 1;Q[l] = S;
while(l<r) {
int u = Q[l++];
for(int i = first[u];i;i=a[i].next)
if(d[a[i].v] == -1 && a[i].w) d[a[i].v] = d[u] + 1,Q[r++] = a[i].v;
}
return d[T] != -1;
}
inline double dfs(int u,double cap) {
if(u == T || cap == 0) return cap;
double Ans = 0.0;
for(int i = first[u];i;i=a[i].next) {
register int v = a[i].v; double w = a[i].w;
if(d[v] == d[u] + 1 && w) {
w = dfs(v,min(w,cap - Ans));
Ans += w;
a[i].w -= w;
a[i^1].w += w;
if(Ans == cap) return Ans;
}
}
if(Ans == 0) d[u] = -1;
return Ans;
}
inline double dinic(){
double Ans = 0.0;
while(bfs()) Ans += dfs(S,inf);
return Ans;
}
inline void build_limit(int u){
int sz = G[u].size();
for(int i = 0;i<sz;i++) push(u,G[u][i],inf);
}
inline void __dfs__(int);
}QAQ,QWQ;
inline void Max_flow::__dfs__(int u){
if(vis[u]) return; vis[u] = 1;
double l = 0.0,r = 0.0,Ans,mid;
for(int i = first[u];i;i=a[i].next) {
__dfs__(a[i].v);
r = max(r,f[a[i].v] + 1.0);
}
while(l+1e-7<r) {
Ans = 0.0; mid = (l + r)/2.0; QWQ.clear();
for(int i = first[u];i;i=a[i].next) {
register int v = a[i].v; QWQ.build_limit(a[i].id);
if(f[v] + 1 < mid) QWQ.push(S,a[i].id,mid - f[v] - 1);
else QWQ.push(a[i].id,T,f[v] + 1 - mid),Ans += f[v] + 1 - mid;
}
if(Ans > QWQ.dinic()) f[u] = mid , l = mid;
else r = mid;
}
// f[u] = max(f[v] + 1 / num > L)
// --> f[v] + 1 - num * L > 0;
// --> sigema(f[v] + 1 - num) > 0;
}
int main(){
n = read<int>();m = read<int>(); k = read<int>();
for(int i = 1;i<=m;i++) {
register int u = read<int>(),v = read<int>();
QAQ.add(u,v,i);
}
for(int i = 1;i<=k;i++) {
register int u = read<int>(),v = read<int>();
G[v].push_back(u);
}
QAQ.__dfs__(1);
printf("%lf\n",f[1]);
return 0;
}