来源:http://poj.org/problem?id=1847
题意:在一个地方,有一些调度站,这些调度站和其他一些调度站之间有路。但是一个调度站只和另一个调度站直接相连,另外和一些调度站间接相连。如果从该调度站到达其直接相连的调度站需要0步,到达其间接相连的调度站需要1步。现在给出了起点和终点,问从起点到终点最少需要多少步。
思路:很明显用bfs可以解决了,但因为涉及到步数增加不一致的问题,所以可以用优先队列做。其实和 POJ 2312是一样的。
代码:
#include <iostream>
#include <cstdio>
#include <string.h>
#include <queue>
#include <vector>
using namespace std;
#define CLR(arr,val) memset(arr,val,sizeof(arr))
struct station{
int id,step;
bool operator < (const station & a)const{
return step > a.step;
}
};
const int N = 110;
int map[N][N],flag[N],n,spos,epos;
bool vis[N][N];
vector<int> vv[N];
int bfs(){
priority_queue<station> qq;
station s;
s.id = spos;
s.step = 0;
flag[spos] = 1;
qq.push(s);
while(!qq.empty()){
station ts = qq.top();
//printf("ts.id = %d\n",ts.id);
//printf("ts.step = %d\n",ts.step);
qq.pop();
if(ts.id == epos){
return ts.step;
}
else{
for(int i = 0; i < vv[ts.id].size(); ++i){
int y = vv[ts.id][i];
if(vis[ts.id][y]){
vis[ts.id][y] = 0;
station news;
news.id = y;
if(map[ts.id][y] == 1){
//printf("y = %d\n",y);
news.step = ts.step;
}
else{
news.step = ts.step + 1;
}
qq.push(news);
}
}
}
}
return -1;
}
int main(){
//freopen("1.txt","r",stdin);
while(scanf("%d%d%d",&n,&spos,&epos) != EOF){
int num,x;
CLR(map,0);
CLR(flag,0);
CLR(vv,0);
CLR(vis,0);
for(int i = 1; i <= n; ++i){
scanf("%d",&num);
for(int j = 1;j <= num; ++j){
scanf("%d",&x);
vv[i].push_back(x);
vis[i][x] = 1;
if(j == 1)
map[i][x] = 1;
else
map[i][x] = 2;
}
}
int ans = bfs();
printf("%d\n",ans);
}
return 0;
}