题意:cows 想用自己手上的商品(编号为1)通过多次交换得到想要的商品(编号为k),给出两种商品的交换关系,求出至少有多少种商品经过交换,输出交换的顺序。
思路:最短路。相当于求从1商品到k商品的最短路径,中间再记录一下结点信息。
#include <stdio.h>
#include <string.h>
#define INF 0xfffffff
#define N 1005
#define M 50005
struct edge{
int y,w,next;
}e[M];
int used[N],dis[N],first[N],pre[N];
int n,m,top;
void add(int x,int y){
e[top].y = y;
e[top].w = 1;
e[top].next = first[x];
first[x] = top++;
}
int dijkstra(){
int i,j,now,min;
memset(used,0,sizeof(used));
for(i = 1;i<=n;i++)
dis[i] = INF;
dis[1] = 0;
for(i = 1;i<=n;i++){
min = INF;
for(j = 1;j<=n;j++){
if(!used[j] && dis[j]<min){
min = dis[j];
now = j;
}
}
if(min == INF)
break;
used[now] = 1;
for(j = first[now];j!=-1;j=e[j].next){
if(!used[e[j].y] && dis[now]+e[j].w < dis[e[j].y]){
dis[e[j].y] = dis[now]+e[j].w;
pre[e[j].y] = now;
}
}
}
if(dis[n] == INF)
return -1;
return dis[n]+1;
}
void print(int i){
if(i>1)
print(pre[i]);
printf("%d\n",i);
}
int main(){
freopen("a.txt","r",stdin);
while(scanf("%d %d",&m,&n)!=EOF){
int i,a,b;
top = 0;
memset(first,-1,sizeof(first));
for(i = 0;i<m;i++){
scanf("%d %d",&a,&b);
add(a,b);
}
i = dijkstra();
printf("%d\n",i);
if(i!=-1)
print(n);
}
return 0;
}
其实用bfs即可。
#include <cstdio>
#include <cstring>
#include <string>
#include <vector>
#include <queue>
using namespace std;
#define N 1005
#define INF 0x7fffffff
struct edge{
int y,next;
}e[50005];
int first[N], dis[N], pre[N];
int top;
bool used[N];
void add(int x, int y){
e[top].y = y;
e[top].next = first[x];
first[x] = top++;
}
void bfs(int n){
queue<int> q;
q.push(1);
memset(used, false, sizeof(used));
memset(dis, 0, sizeof(dis));
memset(pre, -1, sizeof(pre));
used[1] = true;
while(!q.empty()){
int pos = q.front();
q.pop();
for (int j = first[pos]; j!=-1; j = e[j].next){
if(!used[e[j].y]){
used[e[j].y] = true;
dis[e[j].y] = dis[pos]+1;
pre[e[j].y] = pos;
if(e[j].y == n)
return;
q.push(e[j].y);
}
}
}
}
void print(int n){
if(n == -1)
return;
print(pre[n]);
printf("%d\n", n);
}
int main(){
int n,m;
while(scanf("%d %d", &m, &n) != EOF){
int a,b;
top = 0;
memset(first, -1, sizeof(first));
while(m--){
scanf("%d %d",&a, &b);
add(a, b);
}
bfs(n);
if (pre[n] == -1){
printf("-1\n");
}else{
printf("%d\n", dis[n]+1);
print(n);
}
}
return 0;
}