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;
} 

猜你喜欢

转载自www.cnblogs.com/tombraider-shadow/p/11869412.html