SDOI2013 费用流
题目链接:戳我
emmmm就是在可行的最大流里面让最大边最小。我们可以进行二分+限流然后跑dinic,看是否能跑满即可。
代码如下:
#include<iostream>
#include<cstring>
#include<cstdio>
#include<algorithm>
#include<cmath>
#include<queue>
#define eps 1e-6
#define S 1
#define T n
#define MAXN 100010
#define INF 1e9
using namespace std;
int n,m,t=1,p;
int head[MAXN<<1],dep[MAXN],cur[MAXN<<1];
double maxx;
struct Edge{int nxt,to;double dis;}edge[MAXN<<1],pre[MAXN<<1];
inline void add(int from,int to,double dis)
{
edge[++t].nxt=head[from],edge[t].to=to,edge[t].dis=dis,head[from]=t;
edge[++t].nxt=head[to],edge[t].to=from,edge[t].dis=0,head[to]=t;
}
inline bool bfs()
{
queue<int>q;
memset(dep,0x3f,sizeof(dep));
memcpy(cur,head,sizeof(head));
q.push(S);dep[S]=0;
while(!q.empty())
{
int u=q.front();q.pop();
//printf("u=%d\n",u);
for(int i=head[u];i;i=edge[i].nxt)
{
int v=edge[i].to;
//printf("v=%d dep[v]=%d dis=%.2lf\n",v,dep[v],edge[i].dis);
if(dep[v]==0x3f3f3f3f&&edge[i].dis>eps)
dep[v]=dep[u]+1,q.push(v);
}
//puts("");
}
if(dep[T]==0x3f3f3f3f) return false;
return true;
}
inline double dfs(int x,double f)
{
if(f<eps||x==T) return f;
double w,used=0;
for(int i=cur[x];i;i=edge[i].nxt)
{
int v=edge[i].to;
cur[x]=i;
if(dep[v]==dep[x]+1&&(w=dfs(v,min(edge[i].dis,f))))
{
edge[i].dis-=w,edge[i^1].dis+=w;
f-=w,used+=w;
if(f<eps) break;
}
}
return used;
}
inline double dinic()
{
double cur_ans=0;
while(bfs()) cur_ans+=dfs(S,INF);
return cur_ans;
}
inline bool check(double limit)
{
//cout<<"limit="<<limit<<endl;
for(int i=2;i<=t;i++) edge[i].dis=min(pre[i].dis,limit);
//for(int i=2;i<=t;i++) cout<<edge[i].dis<<" ";
double cur_ans=dinic();
//cout<<endl<<"cur_ans="<<cur_ans<<endl;
if(maxx-cur_ans<eps) return true;
return false;
}
int main()
{
#ifndef ONLINE_JUDGE
freopen("ce.in","r",stdin);
#endif
scanf("%d%d%d",&n,&m,&p);
for(int i=1;i<=m;i++)
{
int u,v,w;
scanf("%d%d%d",&u,&v,&w);
add(u,v,w);
}
for(int i=2;i<=t;i++) pre[i].dis=edge[i].dis;
maxx=dinic();
double l=0,r=50000.0;
//cout<<"maxx="<<maxx<<endl;
while(r-l>eps)
{
double mid=(l+r)/2;
if(check(mid)) r=mid;
else l=mid;
}
printf("%d\n",(int)maxx);
printf("%.4lf\n",l*(p*1.0));
return 0;
}