您的位置:首页 > 职场人生

谷歌2014面试题 Problem E. Spaceship Defence(spfa,哈希)

2016-06-09 13:47 471 查看
Description

The enemy has invaded your spaceship, and only superior tactics will allow you to defend it! To travel around your spaceship, your soldiers will use two devices: teleporters and turbolifts.

Teleporters allow your soldiers to move instantly between rooms. Every room contains a teleporter, and rooms are color-coded: if a soldier is in a room with some color, she can use the teleporter in that room to immediately move to any other room
with the same color
.

Turbolifts allow your soldiers to move between rooms more slowly. A turbolift is like an elevator that moves in many directions. Each turbolift moves from one room to one other room, and it takes a certain amount of time to travel. Notes about turbolifts:

Turbolifts are not two-way: if a turbolift moves soldiers from room a to room b, the same turbolift cannot move soldiers from room b to room a, although there might be another turbolift that does that.
More than one soldier can use the same turbolift, and they do not interfere with each other in any way.
You will be given the locations and destinations of several soldiers. For each soldier, output the minimum amount of time it could take that soldier to travel from his location to his destination.

Input

The first line of the input gives the number of test cases, T(1 ≤ T ≤ 10). T test cases follow.

For every test case:

The first line of every test case contains an integer N(1 ≤ N ≤ 80000), which is the number of rooms in your spaceship. The rooms are numbered from 1 to N.

The following N lines each contain a string telling the color of the rooms, from room 1 to room N.

The strings only contain characters a-z (the lower-case English letters) and 0-9 (the number 0 to 9), and the length of each string will be less than or equal to 2.

The next line in the test case is an integer M(0 ≤ M ≤ 3000), which indicates the number of turbolifts in your spaceship. The following Mlines each contain 3 space-separated integers ai, bi, ti(1 ≤ ai,
bi ≤ N, 0 ≤ ti ≤ 1000), telling us that there is a turbolift that can transport soldiers from room ai to room bi in ti seconds.

The next line in the test case contains an integer S(1 ≤ S ≤ 100), which is the number of soldiers at your command. The following S lines each contain two integers: the location and destination of one soldier, pj and qj(1
≤ pj, qj ≤ N).

Output

For each test case, output one line containing only the string "Case #x:", where x is the number of the test case (starting from 1).

On the next S lines, output a single integer: on line j, the smallest number of seconds it could take for a soldier to travel from pj to qj. If there is no path from pj to qj,
the integer you output should be -1.

Sample Input

3
3
gl
t3
t3
3
1 2 217
3 2 567
1 1 21
2
2 1
2 3
4
ca
bl
bl
8z
0
3
1 2
2 3
1 1
8
re
b7
ye
gr
0l
0l
ye
b7
7
4 1 19
2 4 21
2 5 317
4 5 34
4 7 3
4 8 265
8 6 71
3
4 3
2 6
1 4


Sample Output

Case #1:
-1
0
Case #2:
-1
0
0
Case #3:
3
55
-1


题意:给出n个飞船,每个飞船有一种颜色,相同颜色的飞船可以瞬移到彼此,不同颜色的飞船之间有需要到达的时间,给出m个询问,问两两之间怎样到达的时间最少。

思路:由于给出的颜色是字符串,我们不得不思考如何处理字符串,由于题目说字符串最多只有两个字符,所以我用一个字符串对应一个数字,类似于哈希,做一个映射,然后相同颜色的都当做一个点处理,最后询问的时候跑一个spfa就ok。由于把所有同颜色的点当做了一个点,跑完数据只有48ms。

#include <iostream>
#include <stdio.h>
#include <stdlib.h>
#include<string.h>
#include<algorithm>
#include<math.h>
#include<queue>
#include<stack>
using namespace std;
typedef long long ll;
const int N=80005;
const int INF=100000000;
int head
;
int ip;
struct edgenode
{
int to;
int w;
int next;
} tu
;
void init()
{
ip=0;
memset(head,-1,sizeof(head));
}
void add(int u,int v,int w)
{
tu[ip].to=v,tu[ip].w=w,tu[ip].next=head[u],head[u]=ip++;
}

int get(char x)
{
if(x>='0'&&x<='9')
return x-'0'+27;
else
return x-'a'+1;
}
char str
[3];
int f
;
int bj=0;
int gget(int i)///得到映射
{
if(str[i][1]=='\0')
{
if(!f[get(str[i][0])])
return f[get(str[i][0])]=bj++;
else return f[get(str[i][0])];
}
else
{
if(!f[get(str[i][0])*100+get(str[i][1])])
return f[get(str[i][0])*100+get(str[i][1])]=bj++;
else return f[get(str[i][0])*100+get(str[i][1])];
}
}

int dis
;
bool vis
;
int solve(int s,int e,int n)///spfa求最短路
{
queue<int>q;
for(int i=0; i<=n; i++)
dis[i]=INF;
memset(vis,0,sizeof(vis));
q.push(s);
dis[s]=0;
while(!q.empty())
{
int h=q.front();
q.pop();
vis[h]=0;
for (int i=head[h]; i!=-1; i=tu[i].next)
{
int v=tu[i].to;
int w=tu[i].w;
if (dis[v]>dis[h]+w)
{
dis[v]=dis[h]+w;
if (!vis[v])
{
vis[v]=1;
q.push(v);
}
}
}
}
//for(int i=0;i<=n;i++)
// cout<<"dis["<<i<<"]="<<dis[i]<<endl;

if(dis[e]>=INF)
return -1;
return dis[e];
}

int main()
{
int T,n,m,con=1,s;
scanf("%d",&T);
while(T--)
{
init();
bj=1;
memset(f,0,sizeof(f));
scanf("%d",&n);
for(int i=0; i<n; i++)
{
scanf("%s",str[i]);
gget(i);
}
scanf("%d",&m);
for(int i=0; i<m; i++)
{
int a,b,tt;
scanf("%d%d%d",&a,&b,&tt);
if(gget(a-1)!=gget(b-1))
add(gget(a-1),gget(b-1),tt);
}
scanf("%d",&s);
printf("Case #%d:\n",con++);
for(int i=0; i<s; i++)
{
int st,e;
scanf("%d%d",&st,&e);
printf("%d\n",solve(gget(st-1),gget(e-1),bj-1));
}
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  acm 大二