hdu3790 最短路径问题--单源最短路径

原题链接: http://acm.hdu.edu.cn/showproblem.php?pid=3790


一:原题内容

Problem Description
给你n个点,m条无向边,每条边都有长度d和花费p,给你起点s终点t,要求输出起点到终点的最短距离及其花费,如果最短距离有多条路线,则输出花费最少的。
 
Input
输入n,m,点的编号是1~n,然后是m行,每行4个数 a,b,d,p,表示a和b之间有一条边,且其长度为d,花费为p。最后一行是两个数 s,t;起点s,终点。n和m为0时输入结束。
(1<n<=1000, 0<m<100000, s != t)
 
Output
输出 一行有两个数, 最短距离及其花费。
 
Sample Input
  
  
3 2 1 2 5 6 2 3 4 5 1 3 0 0

Sample Output
  
  
9 11

二:分析理解

这题很恶心!需要对输入的数据处理一下。不然不对,也就是输入的数据可能是这样的:

3 2
1 2 5 6
1 2 5 5
1 2
注意红色部分,这样的数据你需要处理一下,一开始直接没想到这个问题,,尿了!

三:AC代码

#include<iostream>  
#include<string.h>
#include<algorithm>  

using namespace std;

struct Node
{
	int b;
	int p;
};


int n, m;
int a, d, b, p;
int s, t;
Node node[1005][1005];
int dis[1005];
int cost[1005];
bool visited[1005];

int main()
{
	while (scanf("%d%d", &n, &m) && (n || m))
	{
		memset(node, 0, sizeof(node));
		memset(dis, 0, sizeof(dis));
		memset(cost, 0, sizeof(cost));
		memset(visited, 0, sizeof(visited));

		for (int i = 0; i < m; i++)
		{
			scanf("%d%d%d%d", &a, &d, &b, &p);

			if (node[a][d].b == 0 || b < node[a][d].b)
			{
				node[a][d].b = node[d][a].b = b;
				node[a][d].p = node[d][a].p = p;
			}
			else if(b==node[a][d].b&&p<node[a][d].p)
				node[a][d].p = node[d][a].p = p;
		}

		scanf("%d%d", &s, &t);

		for (int i = 1; i <= n; i++)
		{
			if (i != s&&node[s][i].b != 0)
			{
				dis[i] = node[s][i].b;
				cost[i] = node[s][i].p;
			}
			else
			{
				dis[i] = INT_MAX;
				cost[i] = 99999999;
			}
		}

		dis[s] = 0;
		cost[s] = 0;
		visited[s] = true;

		for (int i = 1; i <= n - 1; i++)
		{
			int min = INT_MAX;
			int minPos;
			int cos;
			for (int j = 1; j <= n; j++)
			{
				if (!visited[j] && dis[j] < min)
				{
						min = dis[j];
						minPos = j;
						cos = cost[j];
				}
			}

			visited[minPos] = true;

			for (int k = 1; k <= n; k++)
			{
				if (!visited[k] && node[minPos][k].b != 0)
				{
					if (node[minPos][k].b + min < dis[k])
					{
						dis[k] = node[minPos][k].b + min;
						cost[k] = node[minPos][k].p + cos;
					}
					else if (node[minPos][k].b + min == dis[k])
					{
						if (node[minPos][k].p + cos < cost[k])
							cost[k] = node[minPos][k].p + cos;
					}
				}
			}

		}

		printf("%d %d\n", dis[t], cost[t]);
	}

	return 0;
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值