天天看点

poj 2457 dijkstra(星星之间买牛奶)

题意: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;
}