zoukankan      html  css  js  c++  java
  • [Usaco2014 Feb] Roadblock

    有一个无向图,共N个节点,编号1至N,共M条边。FJ在节点1,它想到达节点N。FJ总是会选择最短路径到达节点N

    。作为捣蛋的奶牛Bessie,它想尽量延迟FJ到达节点N的时间,于是Bessie决定从M条边之中选择某一条边,使得改
    边的长度变成原来的两倍,由于智商的问题,Bessie不知道选择加倍哪条边的长度才能使得FJ到达N号节点的时间
    最迟。注意:不管Bessie选择加倍哪条边的长度,FJ总是会从1号节点开始走最短路径到达N号点。

    Input

    第一行,两个整数N和M. 1 <=N<=250, 1<=M<=250000。

    接下来有M行,每行三个整数:A,B,L,表示节点A和节点B之间有一条长度为L的无向边。1<=L<=1000000。

    Output

    一个整数。Bessie选择了加倍某一条边的长度后,奶牛FJ从节点1到达节点N的最短路径是多少。但是输出的格式
    有变化,假设Bessie没有加倍某一条边的长度之前,FJ从1号节点到达N号节点的最短路径是X;在Bessie加倍某一
    条边的长度之后,FJ从1号节点到达N号节点的最短路径是Y,那么你输出的结果是Y-X。

    Sample Input

    5 7

    2 1 5

    1 3 1

    3 2 8

    3 5 7

    3 4 3

    2 4 7

    4 5 2

    INPUT DETAILS: There are 5 fields and 7 pathways. Currently, the shortest path from the house (field 1) to the barn (field 5) is 1-3-4-5 of total length 1+3+2=6.
    Sample Output

    2

    (把节点3到节点4的边从原来的长度3变成长度6)

    #include<iostream>
    #include<cstdio>
    #include<algorithm>
    #include<cstring>
    #include<cmath>
    #include<map>
    #include<queue>
    #include<set>
    #define ll long long
    #define llu unsigned ll
    using namespace std;
    const int mod=1000000007;
    const int maxn=50100;
    const int maxx=300;
    const int inf=0x3f3f3f3f;
    int head[maxx],edge[maxn],ver[maxn],nt[maxn];
    int d[maxx];
    int ha[maxx];
    int pre[maxx];
    int tot=1,n,m;
    bool flag=false;
    
    void add(int x,int y,int z)
    {
        ver[++tot]=y,edge[tot]=z;
        nt[tot]=head[x],head[x]=tot;
    }
    
    int Dij(void)
    {
        memset(d,0x3f,sizeof(d));
        memset(ha,0,sizeof(ha));
        d[1]=0;
        priority_queue<pair<int,int> >q;//默认为大根堆 
        q.push(make_pair(0,1));
        while(q.size())
        {
            int x=q.top().second;
            q.pop();
            if(ha[x]) continue;
            ha[x]=true;
            for(int i=head[x];i;i=nt[i])
            {
                int y=ver[i],z=edge[i];
                if(d[y]>d[x]+z)
                {
                    d[y]=d[x]+z;
                    if(!flag) //最开始算最短路时,记上y点在最短路上的父亲边是哪条边 
                        pre[y]=i;
                    q.push(make_pair(-d[y],y));
                }
            }
        }
        return d[n];
    }
    
    
    int main(void)
    {
        scanf("%d%d",&n,&m);
        int x,y,z;
        for(int i=1;i<=m;i++)
        {
            scanf("%d%d%d",&x,&y,&z);
            add(x,y,z);
            add(y,x,z);
        }
        int cnt=Dij();
        flag=true;
        int _max=0;
        for(int i=2;i<=n;i++)//枚举点 
        {
            int k=pre[i];
            if (k==0)//如果不在最短路径上就不管了 
    		 continue;
            edge[k]=edge[k]*2,edge[k^1]=edge[k^1]*2;
            _max=max(_max,Dij());
            edge[k]=edge[k]/2,edge[k^1]=edge[k^1]/2;
        }
        printf("%d\n",_max-cnt);
        return 0;
    }
    

      

  • 相关阅读:
    OCP-1Z0-053-V13.02-638题
    OCP-1Z0-053-200题-60题-637
    OCP-1Z0-053-V13.02-637题
    OCP-1Z0-053-200题-47题-625
    OCP-1Z0-053-V13.02-625题
    OCP-1Z0-053-200题-42题-621
    OCP-1Z0-053-V13.02-621题
    OCP-1Z0-053-200题-41题-620
    OCP-1Z0-053-V13.02-620题
    OCP-1Z0-053-200题-37题-616
  • 原文地址:https://www.cnblogs.com/cutemush/p/11772799.html
Copyright © 2011-2022 走看看