Time Limit: 3000MS | Memory Limit: Unknown | 64bit IO Format: %lld & %llu |
Description
Problem A
Galactic Travel
Input: Standard Input
Output: Standard Output
Thanks to the Interstate Highway System, it is now possible |
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, N. N test cases follow. Each one starts with two lines containing n (1 ≤ n ≤ 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;
}