• SCU 4444 Travel


    $BFS$。

    如果$1$和$n$之间存在一条长度为$b$的边,那么还需要去计算只走长度为$a$的边的最小时间。

    如果$1$和$n$之间存在一条长度为$a$的边,那么还需要去计算只走长度为$b$的边的最小时间。

    第一种情况直接$BFS$即可。

    第二种情况需要反过来思考,因为补图的边太多了,对于$BFS$某一层的点,如果当前已经确定最短路径的点的个数大于与它直接相连的确定最短路径的点的个数,那么这个点也可以确定最短路径了。

    #include <bits/stdc++.h>
    using namespace std;
    
    int n,m;
    long long a,b;
    int h[200010];
    int nx[500010*2],to[500010*2];
    long long dis[200010];
    long long INF = 1e18;
    int sz;
    
    void add(int A,int B)
    {
        to[sz]=B;
        nx[sz] = h[A];
        h[A]=sz++;
    }
    
    void xiang578()
    {
        queue<int>Q;
        for(int i=1;i<=n;i++) dis[i] = INF;
        dis[1]=0; Q.push(1);
    
        while(!Q.empty())
        {
            int t = Q.front(); Q.pop();
    
            for(int i=h[t];i!=-1;i=nx[i])
            {
                if(dis[t]+a<dis[to[i]])
                {
                    dis[to[i]] = dis[t]+a;
                    Q.push(to[i]);
                }
            }
        }
    }
    
    void work()
    {
        queue<int>Q[2]; int now=n;
        for(int i=1;i<=n;i++) dis[i] = b;
        dis[1]=0;
        for(int i = h[1];i!=-1;i=nx[i])
        {
            Q[0].push(to[i]);
            dis[to[i]]=INF;
            now--;
        }
    
        int k=0;
        for(int c=2;;c++)
        {
            int ff=0;
            while(!Q[k].empty())
            {
                int t=Q[k].front();Q[k].pop();
    
                int sum=0;
                for(int i=h[t];i!=-1;i=nx[i])
                {
                    if(dis[to[i]]<c*b) sum++;
                }
    
                if(sum==now) Q[k^1].push(t);
                else
                {
                    dis[t] = c*b;
                    ff++;
                }
            }
            k=k^1;
            now=now+ff;
            if(ff==0) break;
        }
    }
    
    int main()
    {
        while(~scanf("%d%d%lld%lld",&n,&m,&a,&b))
        {
            memset(h,-1,sizeof h);
            sz=0;
            int f=0;
            for(int i=1;i<=m;i++)
            {
                int u,v; scanf("%d%d",&u,&v);
                add(u,v);
                add(v,u);
                if(u==1&&v==n) f=1;
                if(v==1&&u==n) f=1;
            }
            if(f==0)
            {
                xiang578();
                printf("%lld
    ",min(b,dis[n]));
            }
    
            else
            {
                work();
                printf("%lld
    ",min(a,dis[n]));
            }
        }
        return 0;
    }
  • 相关阅读:
    不得不说微信之怪现状
    新手运营如何做广告位投放
    网络营销人员如何培养创新技能
    GoDaddy开通中文客服电话,沟通不再是问题
    为zblog FCKeditor编辑器添加设置字体格式h1 h2功能
    真实手机访问本地电脑网站失败的原因
    数据库简总
    简单总结
    GUI图形用户界面学习
    集合框架
  • 原文地址:https://www.cnblogs.com/zufezzt/p/6648331.html
Copyright © 2020-2023  润新知