zoukankan      html  css  js  c++  java
  • [Luogu P2966][BZOJ 1774][USACO09DEC]牛收费路径Cow Toll Paths

    原题全英文的,粘贴个翻译题面,经过一定的修改。

    跟所有人一样,农夫约翰以宁教我负天下牛,休叫天下牛负我的伟大精神,日日夜夜苦思生财之道。为了发财,他设置了一系列的规章制度,使得任何一只奶牛在农场中的道路行走,都要向农夫约翰上交过路费。 农场中由N(1 <= N <= 250)片草地(标号为1到N),并且有M(1 <= M <= 10000)条双向道路连接草地i和j(1 <= i,j <= N)。

    奶牛们从任意一片草地出发可以抵达任意一片的草地。FJ已经在连接i和j的双向道路上设置一个过路费L[i] (1 <= L[i] <= 100,000)。可能有多条道路连接相同的两片草地,但是不存在一条道路连接一片草地和这片草地本身。最值得庆幸的是,奶牛从任意一篇草地出发,经过一系列的路径,总是可以抵达其它的任意一片草地。 除了贪得无厌,叫兽都不知道该说什么好。

    FJ竟然在每片草地上面也设置了一个过路费C[i] (1 <= C[i] <= 100000)。从一片草地到另外一片草地的费用,是经过的所有道路的过路 费之和,加上经过的所有的草地(包括起点和终点)的过路费的最大值。 任劳任怨的牛们希望去调查一下她们应该选择那一条路径。

    她们要你写一个程序,接受K(1 <= K <= 10,000)个问题并且输出每个询问对应的最小花费。第i个问题包含两个数字s[i] 和t[i](1 <= s[i] <= N; 1 <= t[i] <= N; s[i] != t[i]),表示起点和终点的草地。

    ---------------------------------------------------------------分割线QAQ----------------------------------------------------------------------

    看下数据范围,n = 250,而且询问是多源最短路,显然一套floyd就能处理。再考虑一下要加上路径上的点权最大值。维护两个数组dis和ans,dis是floyd板子最短路,ans是加上点权之后的最短路,分别维护比较方便。我们可以按点权从小到大的顺序枚举中转点k,由于k是从小到大枚举的,所以可以取最后的k作为i->j的路径上除i,j外点权的最大值,但由于i,j从1到n枚举,所以再和i,j取max就是路径上最大的点权。

    参考代码:

    #include<cstdio>
    #include<algorithm>
    using namespace std;
    #define qwq 255
    int dis[qwq][qwq],ans[qwq][qwq],id[qwq];
    int n,m,t;
    struct node
    {
        int id;
        int val;
        friend bool operator < (node a,node b)
        {
            if(a.val == b.val) return a.id < b.id;
            return a.val < b.val;
        }
    }a[qwq];
    void floyd()
    {
        for(int k = 1;k <= n;k++)
        {
            for(int i = 1;i <= n;i++)
            {
                for(int j = 1;j <= n;j++)
                {
                    dis[j][i] = dis[i][j] = min(dis[i][j],dis[i][k] + dis[k][j]);//标准的floyd
                    ans[j][i] = ans[i][j] = min(ans[i][j],dis[i][j] + max(a[k].val,max(a[i].val,a[j].val)));//对i->j的最短路,枚举中转点点权最大值
                }
            }
        }
        return;
    }
    int main()
    {
        scanf("%d %d %d",&n,&m,&t);
        for(int i = 1;i <= n;i++) 
        {
            scanf("%d",&a[i].val);
            ans[i][i] = a[i].val;
            a[i].id = i;
        }
        for(int i = 1;i <= n;i++)
        {
            for(int j = 1;j <= n;j++)
            {
                dis[j][i] = dis[i][j] = 1e9;
                if(i != j) ans[i][j] = ans[j][i] = 1e9;
            }
            dis[i][i] = 0;
        }
        sort(a + 1,a + n + 1);
        for(int i = 1;i <= n;i++)
            id[a[i].id] = i;
        for(int i = 1;i <= m;i++)
        {
            int u,v,w;
            scanf("%d %d %d",&u,&v,&w);
            if(w < dis[id[u]][id[v]]) dis[id[u]][id[v]] = dis[id[v]][id[u]] = w;
        }
        floyd();
        while(t--)
        {
            int a,b;
            scanf("%d %d",&a,&b);
            printf("%d
    ",ans[id[a]][id[b]]);
        }
        
    }
  • 相关阅读:
    web.py的input获取问题
    python unicode和 utf8字符串比较
    python default encoding
    linux flash player的问题
    centos 支持 ntfs格式
    学习jqueryjquery中的show()和hide()
    字符串等长分割
    类加载器分类
    类加载器子系统
    70道HR的面试题
  • 原文地址:https://www.cnblogs.com/lijilai-oi/p/10695432.html
Copyright © 2011-2022 走看看