题意:在一个无向图中,所有边的权值为1,求从起点到终点最少要经过多少个顶点。
思路:因为所有边的权值都是一样的,最少步数就是最短路径,用BFS依次搜出即可;也可以用FLoyd求最短路径,代码相比BFS简短。
bfs代码:
#include <iostream>
#include <cstring>
#include <cstdio>
#include <queue>
using namespace std;
const int maxn = 25;
struct node{
int v;
int d;
node(int _v, int _d){
v = _v, d = _d;
}
};
bool edge[maxn][maxn];
bool vis[maxn]; //for bfs
int n;
bool input(){
int v;
int t;
memset(edge,0,sizeof(edge));
for(int i = 1; i <= 19; i++){
if(scanf("%d",&t) != 1) return false;
for(int j = 0; j < t; j++){
scanf("%d",&v);
edge[v][i] = edge[i][v] = true;
}
}
return true;
}
int bfs(int s, int t){
queue<node> q;
memset(vis,0,sizeof(vis));
q.push(node(s,0));
vis[s] = true;
while(!q.empty()){
int u = q.front().v;
int d = q.front().d;
q.pop();
for(int i = 1; i <= 20; i++){
if(edge[u][i] && !vis[i]){
vis[i] = true;
if(i == t) return d+1;
q.push(node(i,d+1));
}
}
}
}
void solve(){
static int cnt = 1;
int s,t;
scanf("%d",&n);
printf("Test Set #%d\n",cnt++);
for(int i = 0; i < n; i++){
scanf("%d%d",&s,&t);
printf("%d to %d: %d\n",s,t,bfs(s,t));
}
puts("");
}
int main(){
while(input()){
solve();
}
return 0;
}
floyd代码:
#include <iostream>
#include <algorithm>
#include <cstring>
#include <cstdio>
using namespace std;
const int inf = 10000;
const int maxn = 25;
int edge[maxn][maxn];
int n;
bool input(){
int v;
int t;
for(int i = 1; i <= 20; i++){
for(int j = 1; j <= 20; j++){
edge[i][j] = inf;
}
}
for(int i = 1; i <= 19; i++){
if(scanf("%d",&t) != 1) return false;
for(int j = 0; j < t; j++){
scanf("%d",&v);
edge[v][i] = edge[i][v] = 1;
}
}
return true;
}
void floyd(){
for(int k = 1; k <= 20; k++){
for(int i = 1; i <= 20; i++){
for(int j = 1; j <= 20; j++){
edge[i][j] = min(edge[i][j],edge[i][k]+edge[k][j]);
}
}
}
}
void solve(){
static int cnt = 1;
int s,t;
floyd();
scanf("%d",&n);
printf("Test Set #%d\n",cnt++);
for(int i = 0; i < n; i++){
scanf("%d%d",&s,&t);
printf("%d to %d: %d\n",s,t,edge[s][t]);
}
puts("");
}
int main(){
while(input()){
solve();
}
return 0;
}