• BZOJ3597: [Scoi2014]方伯伯运椰子


    1.jpg
    2.jpg
    3.jpg

    输入格式:

    第1 行包含2 个整数n,m
    接下来m 行代表m 条边,表示这个交通网络。
    每行6 个整数,表示ui,vi,ai,bi,ci,di.
    接下来1 行包含1 条边,表示连接起点的边

    输出格式:

    一个浮点数,保留2 位小数,表示要求的答案,数据保证答案大于0

    样例输入:

    6 7
    1 2 0 0 1 1000
    2 4 0 0 1 1000
    4 6 0 0 1 1000
    1 3 0 0 0 0
    3 5 0 0 0 0
    5 6 0 0 0 0
    6 8 0 0 1 0
    7 1 0 0 1 0

    样例输出:

    500.00

    数据范围:

    4.jpg

    时间限制:

    3s

    空间限制:

    64M
    具体思路:要求的答案好奇怪啊,好像很像分数规划啊
    那么就用分数规划做吧
    根据套路,我们要二分一下答案
    然后怎么办办勒
     
    发现由于原图是满流的,所以最优方案一定是从一个点到另一个点的一条路径+1流量,另一条-1流量
    那么对于流量>0的边,可以加流量,那就连一条长为单位流量+加流量需要的代价,也可以减流量那就连一条长为-单位流量+减流量需要的代价的反向边
    对于流量为0的边,就只可以加流量了
    然后把每个边的长+mid(二分的答案)然后SPFA判一下有无负环就好了
     
    AC代码:
    复制代码
    #include<bits/stdc++.h>
    #define INF 100000000
    const double eps=1e-6;
    using namespace std;
    int x,y,n,m,i,j,top=1,A,B,C,D,first[200000],next[200000],last[200000],to[200000];
    int bo[200000];
    double dis[200000],len[200000],ans;
    void add(int x,int y,int l)
    {
        top++,to[top]=y,len[top]=(double)l;
        if(first[x]==0)first[x]=top;else next[last[x]]=top;
        last[x]=top;
    }
    void SPFA(int x,double mid)
    {
        if(ans)return;
        bo[x]=true;
        for(int i=first[x];i;i=next[i])
        if(dis[x]+len[i]+mid<dis[to[i]])
        {
            if(bo[to[i]]||ans)
            {
                ans=1;
                break;
            }
            dis[to[i]]=dis[x]+len[i]+mid;
            SPFA(to[i],mid);
        }
        if(ans)return;
        bo[x]=false;
    }
    bool ok(double mid)
    {
        for(int i=1;i<=n+2;i++)dis[i]=0.0,bo[i]=0;
        for(int i=1;i<=n+2;i++)
        {
            ans=0;SPFA(i,mid);
            if(ans)return true;
        }
        return false;
    }
    int main()
    {
        scanf("%d%d",&n,&m);
        for(i=1;i<=m+1;i++)
        {
            scanf("%d%d%d%d%d%d",&x,&y,&A,&B,&C,&D);
            if(C)add(x,y,D+B),add(y,x,A-D);else add(x,y,B+D);
        }
        
        double l=0,r=1000.0,mid;
        while(r-l>eps)
        {
            mid=(l+r)/2.0;
            if(ok(mid))l=mid;else r=mid;
        }
        printf("%.2lf",mid);
    }
  • 相关阅读:
    Linux的网络配置
    Linux进程
    我需要的电脑配置
    spring注解配置
    spring中集合的配置
    getProperty()方法的参数和用途
    树的遍历
    单词变换
    最短路径dijkstra算法
    文件路径
  • 原文地址:https://www.cnblogs.com/Orange-User/p/8531223.html
Copyright © 2020-2023  润新知