zoukankan      html  css  js  c++  java
  • URAL 2034 Caravans(变态最短路)

    Caravans

    Time limit: 1.0 second
    Memory limit: 64 MB
    Student Ilya often skips his classes at the university. His friends criticize him for this, but they don’t know that Ilya spends this time not watching TV serials or listening to music. He creates a computer game of his dreams. The game’s world is a forest. There are elves, wooden houses, and a villain. And one can rob caravans there! Though there is only one caravan in the game so far, Ilya has hard time trying to implement the process of robbing.
    The game world can be represented as several settlements connected by roads. It is possible to get from any settlement to any other by roads (possibly, passing through other settlements on the way). The settlements are numbered by integers from 1 to n. All the roads are two-way and have the same length equal to 1. It is not allowed to move outside the roads. The caravan goes from settlement s to settlement f following one of the shortest routes. Settlement r is the villain’s den. A band of robbers from settlement r has received an assignment to rob the caravan. In the evening they will have an exact plan of the route that the caravan will take the next morning. During the night they will be able to move to any settlement on the route, even to settlement s or f. They will lay an ambush there and rob the caravan in the morning. Of course, among all such settlements the robbers will choose the one closest to settlement r. The robbers have a lot of time until the evening. They don’t know the caravan’s route yet, but they want to know the maximum distance they will have to go in the worst case to the settlement where they will rob the caravan. Help Ilya calculate this distance, and it may happen that he will attend his classes again!

    Input

    The first line contains integers n and m (3 ≤ n ≤ 105; 2 ≤ m ≤ 105), which are the number of settlements in the game world and the number of roads between them. Each of the following m lines describes a road. The description contains integers a and b, which are the numbers of the settlements connected by the road. It is guaranteed that each road connects two different settlements and there is at most one road between any two settlements. It is also guaranteed that the road network is connected. In the last line you are given pairwise different integers s, f, and r, which are the numbers of the settlements described above.

    Output

    In the only line output the required distance.

    Sample

    inputoutput
    7 7
    1 2
    2 4
    2 5
    3 4
    4 6
    5 6
    6 7
    1 7 3
    
    2
    

    Notes

    In the sample the caravan may follow either the route 1-2-4-6-7 or the route 1-2-5-6-7. In the first case the robbers lay an ambush in settlement 4, which is at distance 1 from the villain’s den. In the second case the robbers lay an ambush in settlement 2 or settlement 6, which are at distance 2 from the villain’s den. The second variant is worse for the robbers, and it should be chosen as the answer.
    Problem Author: Oleg Merkurev
    【分析】给你一个图,起点和终点还有强盗所在的点,商家运货只走最短路,强盗想劫持这批货,但强盗很懒,只想埋伏在一个离他所在点最近的一个点且那个点在商家的路线上。问强盗最远需要走多少距离,也就是说商家选择的最短路是不定的,也许选择了一条离强盗家最远的那条路,但强盗仍然要埋伏在这条路上离他家最近的那个点上。
    做法就是两次SPFA。第一次用dis数组记录每个点到强盗家的最短路,第二次维护两个数组,d[]记录每个点到s的最短路,ans[]记录强盗需要走的最远的距离。
    #include <iostream>
    #include <cstring>
    #include <cstdio>
    #include <algorithm>
    #include <cmath>
    #include <string>
    #include <map>
    #include <stack>
    #include <queue>
    #include <vector>
    #define inf 0x3f3f3f3f
    #define met(a,b) memset(a,b,sizeof a)
    typedef long long ll;
    using namespace std;
    const int N = 1e5+10;
    const int M = 24005;
    int n,m,k,tot=0,s,t,r;
    int dis[N],head[N],vis[N],ans[N],d[N];
    queue<int>q;
    struct man{
        int to,next;
    }edg[2*N];
    void add(int u,int v){
        edg[tot].to=v;edg[tot].next=head[u];head[u]=tot++;
        edg[tot].to=u;edg[tot].next=head[v];head[v]=tot++;
    }
    void spfa1(int x){
        met(vis,0);met(d,inf);
        vis[x]=1;ans[x]=dis[x];d[x]=0;
        while(!q.empty())q.pop();
        q.push(x);
        while(!q.empty()){
            int u=q.front();q.pop();vis[u]=0;
            for(int i=head[u];i!=-1;i=edg[i].next){
                int v=edg[i].to;
                if(d[v]>d[u]+1){
                    d[v]=d[u]+1;
                    ans[v]=min(ans[u],dis[v]);
                    if(!vis[v]){
                        q.push(v);vis[v]=1;
                    }
                }
                else if(d[v]==d[u]+1 && ans[v]<ans[u]){
                    ans[v]=min(ans[u], dis[v]);
                    if(!vis[v]){
                        q.push(v);vis[v]=1;
                    }
                }
            }
        }
    }
    void spfa(int x){
        met(vis,0);met(dis,inf);
        vis[x]=1;dis[x]=0;
        while(!q.empty())q.pop();
        q.push(x);
        while(!q.empty()){
            int u=q.front();q.pop();vis[u]=0;
            for(int i=head[u];i!=-1;i=edg[i].next){
                int v=edg[i].to;
                if(dis[v]>dis[u]+1){
                    dis[v]=dis[u]+1;
                    if(!vis[v]){
                        q.push(v);vis[v]=1;
                    }
                }
            }
        }
    }
    int main() {
        scanf("%d%d",&n,&m);
        int u,v;met(head,-1);
        while(m--){
            scanf("%d%d",&u,&v);
            add(u,v);
        }
        scanf("%d%d%d",&s,&t,&r);
        spfa(r);
        spfa1(s);
        printf("%d
    ",ans[t]);
        return 0;
    }
  • 相关阅读:
    #研发中间件介绍#定时任务调度与管理JobCenter
    分享一个分布式定时任务系统 ( python)
    APScheduler + Gearman 构建分布式定时任务调度-std1984-ITPUB博客
    分布式缓存的一起问题 – 后端技术 by Tim Yang
    新兵训练营系列课程——Feed架构介绍
    Mysql分库分表方案
    可扩展性设计之数据切分
    你的数据库数据量上亿,为了提高效率,要分库还是分表?具体怎么做
    58同城mysql分库分表实践-沈剑
    可动态扩展的分库分表策略浅谈
  • 原文地址:https://www.cnblogs.com/jianrenfang/p/6000747.html
Copyright © 2011-2022 走看看