CODEFORCES-CONTEST653-D. Delivery Bears
D. Delivery Bears
题目大意:给你一个网络图(有向边,有权值)和m头熊,问在m头熊搬运同样重的货物下,我能从1到n最多运送多少货物
解题思路:最大流加二分图,首先我们需要考虑,我们最多能运多少货物到n,假设为f,因此我们每一条边都能通过c/f头牛,c为
边的权值,因此我们以c/f为边的容量,看看我能最多同时走几头牛,二分查找即可。
特殊数据:
3 2 100000 1 2 1 2 3 1000000
//
1.0000000000
代码:
#include<bits/stdc++.h> using namespace std; typedef long long ll; const int maxn=1e4+10; const int inf=0x3f3f3f; struct no { ll next; ll to; ll val; ll f; }edge[maxn],edge2[maxn]; int cnt; int head[maxn]; int belong[maxn]; int dep[maxn]; int a[maxn]; int n,m,x,s,t; double mid; void add(int u,int v,int w) { edge[cnt].to=v,edge[cnt].val=w,edge[cnt].next=head[u]; head[u]=cnt++; edge[cnt].to=u,edge[cnt].val=0,edge[cnt].next=head[v]; head[v]=cnt++; } bool bfs() { memset(dep,0,sizeof(dep)); dep[s]=1; queue<int>q; q.push(s); while(!q.empty()) { int u=q.front(); q.pop(); for(int i=head[u];i!=-1;i=edge[i].next) { int v=edge[i].to; if(!dep[v]&&edge[i].f>0) { dep[v]=dep[u]+1; q.push(v); } } } return dep[t]; } int dfs(int u,int maxflow) { ll tempflow; if(u==t) { return maxflow; } ll add=0; for(int i=head[u];i!=-1;i=edge[i].next) { ll v=edge[i].to; if(dep[v]==dep[u]+1&&edge[i].f>0&&(tempflow=dfs(v,min(maxflow-add,edge[i].f)))) { edge[i].f-=tempflow; edge[i^1].f+=tempflow; add+=tempflow; if(maxflow==add) break; } } return add; } int dicnic() { int ans=0; while(bfs()) { int temp; while(temp=dfs(s,inf)) ans+=temp; } //cout<<ans<<endl; return ans; } int maps[1500][1500]; bool check(double x1) { for(int i=0;i<cnt;i++) edge[i].f=(int)edge[i].val/x1; int t=dicnic(); if(t>=x) return true; else return false; } int main() { cin>>n>>m>>x; s=1,t=n; memset(head,-1,sizeof(head)); for(int i=1;i<=m;i++) { int a,b,c; cin>>a>>b>>c; add(a,b,c); maps[a][b]=c; if(maps[b][a]==0) add(b,a,0); } float l=0,r=1e10,mid; for(int i=0;i<=100;i++) { mid=(r+l)/2; if(check(mid)) l=mid; else r=mid; } printf("%.10lf\n",l*x); return 0; }