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

      

  • 相关阅读:
    hdu 1455 N个短木棒 拼成长度相等的几根长木棒 (DFS)
    hdu 1181 以b开头m结尾的咒语 (DFS)
    hdu 1258 从n个数中找和为t的组合 (DFS)
    hdu 4707 仓鼠 记录深度 (BFS)
    LightOJ 1140 How Many Zeroes? (数位DP)
    HDU 3709 Balanced Number (数位DP)
    HDU 3652 B-number (数位DP)
    HDU 5900 QSC and Master (区间DP)
    HDU 5901 Count primes (模板题)
    CodeForces 712C Memory and De-Evolution (贪心+暴力)
  • 原文地址:https://www.cnblogs.com/cutemush/p/11772799.html
Copyright © 2011-2022 走看看