HDU 2544 最短路

/*
最基础的Dijkstra算法
*/
#include <cstdio>
#include <cstring>
const int nMax = 107;
const int INF = 100007;
int w[nMax][nMax];
int d[nMax];

int N, M;
void init()
{
	int i, j;
	for(i = 0; i <= N; ++ i)
		for(j = 0; j <= N; ++ j)
			w[i][j] = INF;
	for(i = 0; i < M; ++ i)
	{
		int a, b, c;
		scanf("%d %d %d", &a, &b, &c);
		w[a][b] = w[b][a] = c;//无向图
	}
}
void dijkstra()
{
	bool v[nMax];
	memset(v, 0, sizeof(v));//用一个数组来表示集合S
	d[1] = 0;
	int i;
	for(i = 2; i <= N; ++ i) d[i] = INF;
	for(i = 0; i < N; ++ i)
	{
		int x, m = INF;
		int j;
		//找出最小距离
		for(j = 1; j <= N; ++ j) if(!v[j] && d[j] < m) m = d[x = j];
		//加入到S集合
		v[x] = 1;
		//更新数据
		for(j = 1; j <= N; ++ j) if(!v[j] && d[x] + w[x][j] < d[j])
			d[j] = d[x] + w[x][j];
	}
}
int main()
{
	//freopen("f://data.in", "r", stdin);
	while(scanf("%d %d", &N, &M) != EOF)
	{
		if(!N && !M) break;
		init();
		dijkstra();
		printf("%d\n", d[N]);
	}
	return 0;
}

//WA,但不知道错误出在哪里

/*
改进版:稀疏图的邻接表
*/
#include <cstdio>
#include <cstring>
#include <queue>
using namespace std;
const int nMax = 107;
const int INF = 100007;
int d[nMax];
struct Node
{
	bool operator<(Node T)const {return T.dis < dis;}
	int x;
	int dis;
	Node(){}
	Node(int x, int dis):x(x), dis(dis){}
};
priority_queue<Node> Q;

struct Adj
{
	int x;
	Adj *next;
	int w;
	Adj(){next = NULL;}
}adj[nMax];

int N, M;
void buildAdjList(int a, int b, int c)
{
	Adj *q = &adj[a];//第一个为空
	while(q->next != NULL)
		q = q->next;
	Adj *p = new Adj;
	p->w = c;
	p->x = b;
	p->next = NULL;
	q->next = p;
}
void init()
{
	int i;
	for(i = 0; i < M; ++ i)
	{
		int a, b, c;
		scanf("%d %d %d", &a, &b, &c);
		buildAdjList(a, b, c);
		buildAdjList(b, a, c);
	}
}
void dijkstra()
{
	int hash[nMax];
	memset(hash, 0, sizeof(hash));//用一个数组来表示集合S
	d[1] = 0;
	int i;
	for(i = 2; i <= N; ++ i) d[i] = INF;
	while(!Q.empty())
		Q.pop();
	Q.push(Node(1,0));
	while(!Q.empty())
	{
		Node e = Q.top();
		Q.pop();
		int x = e.x;
		if(x == N)
			break;
		if(hash[x])
			continue;
		hash[x] = 1;
		Adj *p = adj[x].next;
		while(p)
		{
			if(!hash[p->x] && d[x] + p->w < d[p->x])
			{
				d[p->x] = d[x] + p->w;
				Q.push(Node(p->x,d[p->x]));
			}
			p = p->next;
		}
	}
}
int main()
{
	//freopen("f://data.in", "r", stdin);
	while(scanf("%d %d", &N, &M) != EOF)
	{
		if(!N && !M) break;
		init();
		dijkstra();
		printf("%d\n", d[N]);
	}
	return 0;
}

//Bellman-Ford算法实现。
#include <cstdio>
#include <cstring>
const int nMax = 107;
const int mMax = 10007;
const int INF = 1000007;
int N, M;
struct Edge
{
	int u;
	int v;
	int w;
}edge[mMax];
int d[nMax];
void init()
{
	int i;
	for(i = 0; i < M; ++ i)
		scanf("%d %d %d", &edge[i].u, &edge[i].v, &edge[i].w);
	for(i = 2; i <= N; ++ i)
		d[i] = INF;
	d[1] = 0;
}
void BellmanFord()
{
	int i, j;
	for(i = 0; i < N - 1; ++ i)
		for(j = 0; j < M; ++ j)
		{
			int x = edge[j].u;
			int y = edge[j].v;
			if(d[y] > d[x] + edge[j].w)
				d[y] = d[x] + edge[j].w;
			if(d[x] > d[y] + edge[j].w)//无向图
				d[x] = d[y] + edge[j].w;
		}
}
int main()
{
	//freopen("f://data.in", "r", stdin);
	while(scanf("%d %d", &N, &M) != EOF)
	{
		if(!N && !M) break;
		init();
		BellmanFord();
		printf("%d\n", d[N]);
	}
	return 0;
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值