uva 11165 Galactic Travel

Time Limit: 3000MSMemory Limit: Unknown64bit IO Format: %lld & %llu

[Submit]   [Go Back]   [Status]  

Description


Problem A
Galactic Travel 
Input: 
Standard Input

Output: Standard Output

 

Thanks to the Interstate Highway System, it is now possible
to travel from coast to coast without seeing anything.

Charles Kuralt

The problem is simple: there are n planets in the galaxy that have human settlements on them. Each planet has a hyperspace jump gate that allows a space ship to teleport from some planet U to some planet V. For technical reasons, not all of the  n( n - 1)  jumps are allowed. What is the smallest number of jumps that are required to reach planet T from planet S?

Input
The first line of input gives the number of cases, NN test cases follow. Each one starts with two lines containing n  (1 ≤  ≤ 100,000)  and k  (0 ≤  k ≤ 41,000) . The next k lines will each be of the form
    U V1-V2

meaning that the jumps from planet U to planets V1 through V2 (inclusive) are forbidden. Finally, the last line will contain S and T. Vertices are numbered from 0 to  n -1 . The number of different forbidden pairs will be no larger than  5,000,000 .

 

Output
For each test case, output one line containing "Case #x:" followed by either the minimum number of jumps, or "Impossible".

 

Sample Input                                  Output for Sample Input

4
3
1
0 2-2
0 2
3
1
0 1-2
0 2
4
4
0 0-3
1 0-3
2 0-3
3 0-3
0 0
100000
3
0 1-99998
99999 1-50000
99999 50002-99999
0 1
Case #1: 2
Case #2: Impossible
Case #3: 0
Case #4: 3

 


Problem setter: Igor Naverniouk

Special Thanks: Joachim Wulff

 

 给出原图的补图,求原图上两点的最短路。bfs,直接对原图做bfs肯定不行。参考了论坛里的思路,用一个链表存储还有哪些点没有被访问过,每个点存下被ban掉的那些区间并排序,之后对每个点的拓展就可以用two pointer的方法,这样复杂度就是O(n+k)了。

#include<cstdio>
#include<map>
#include<queue>
#include<cstring>
#include<iostream>
#include<cstring>
#include<algorithm>
#include<vector>
#include<list>
#include<set>
using namespace std;
const int maxn = 100000 + 5;
const int INF = 1000000000;
typedef long long LL;
typedef pair<int, int> P;
#define fi first
#define se second

vector<P> G[maxn];
list<int> li;
list<int>::iterator it;
queue<P> q;
vector<list<int>::iterator > v;

int bfs(int s, int t){
    while(!q.empty())
        q.pop();
    q.push(P(s, 0));
    while(!q.empty()){
        int pos = q.front().fi;
        int cnt = q.front().se;
        if(pos == t)
            return cnt;
        q.pop();
        v.clear();
        it = li.begin();
        int it2 = 0;
        int Size = G[pos].size();
        while(it != li.end() && it2 < Size){
            int l = G[pos][it2].fi;
            int r = G[pos][it2].se;
            if(*it < l){
                q.push(P(*it, cnt+1));
                v.push_back(it);
                it++;
            }
            else if(*it >= l && *it <= r){
                it++;
            }
            else{
                it2++;
            }
        }
        for(;it != li.end();it++){
            q.push(P(*it, cnt+1));
            v.push_back(it);
        }
        for(int i = 0;i < v.size();i++){
            li.erase(v[i]);
        }
    }
    return INF;
}

int main(){
    int t, kase = 0;
    scanf("%d", &t);
    while(t--){
        kase++;
        int n, k;
        scanf("%d%d", &n, &k);
        for(int i = 0;i < n;i++)
            G[i].clear();
        while(k--){
            int x, from, to;
            scanf("%d%d-%d", &x, &from, &to);
            G[x].push_back(P(from, to));
        }
        li.clear();
        for(int i = 0;i < n;i++){
            li.push_back(i);
            sort(G[i].begin(), G[i].end());
        }
        int s, t;
        scanf("%d%d", &s, &t);
        li.remove(s);
        int ans = bfs(s, t);
        printf("Case #%d: ", kase);
        if(ans == INF)
            printf("Impossible\n");
        else
            printf("%d\n", ans);
    }
    return 0;
}


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值