hduoj3790:最短路径问题

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

这一题是一道双权值的问题,并且权值有主要与次要之分,这里我们仍采用dijkstra算法,不过在建图的时候我们需要多保存一条信息,就是第二个权值,在表示源点到目标点的代价的时候我们用一个二维数组来保存。然后更新的时候每个点仍只访问一次,可以保证最后结果的正确性,这里就不说其证明了(证明很简单)

代码如下:

#include <iostream>
#include <stdio.h>
#include <string.h>
#include <queue>

using namespace std;

#define INF 10000000
const int maxn = 1005 ;

struct Node
{
	int x  ;
	int in ;
	int y  ;
};

int dist[maxn][2] ;
int map[maxn][maxn][2] ;
int vis[maxn] ;

int n ;
int m ;
int s ;
int t ;

void init() ;
bool operator<(Node a , Node b)
{
	if(a.x != b.x )
		return a.x > b.x ;

	return a.y > b.y ;
}

void dijkstra(int ) ;

int main()
{
	int i ;
	int p ;
	int q ;
	int w ;
	int x ;

	//freopen("data.in" , "r" , stdin) ;

	while(scanf("%d%d" , &n , &m)!=EOF &&(m!=0 && n!=0))
	{
		init() ;

		for(i = 1 ; i <= m ; i ++)
		{
			scanf("%d%d%d%d" ,&p , &q ,&w , &x) ;

			if(map[p][q][0] > w )
			{
				map[p][q][0] = w ;
				map[p][q][1] = x ;
				map[q][p][0] = w ;
				map[q][p][1] = x ;
			}
			else if(map[p][q][0]== w && map[p][q][1] > x)
			{
				map[p][q][0] = w ;
				map[p][q][1] = x ;
				map[q][p][0] = w ;
				map[q][p][1] = x ;
			}
		}

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

		dijkstra(s) ;

		printf("%d %d\n" , dist[t][0] , dist[t][1]) ;
	}
    return 0;
}

void init()
{
	int i ;
	int j ;

	for(i = 0 ; i < maxn ; i ++)
	{
		dist[i][0] = INF ;
		vis[i] = 0 ;
		for( j = 0 ; j < maxn ; j ++)
		{
			map[i][j][0] = INF ;
			map[i][j][1] = 0 ;
		}
	}
}

void dijkstra(int s)
{
	int i ;
	Node a ;
	Node b ;

	priority_queue<Node> Q ;

	dist[s][0] = 0 ;
	dist[s][1] = 0 ;

	a.x = 0 ;
	a.y = 0 ;
	a.in = s ;

	Q.push(a) ;

	while(!Q.empty())
	{
		a = Q.top() ;
		Q.pop() ;

		if(vis[a.in])
			continue ;

		vis[a.in] ++ ;

		for(i = 1 ; i <= n ; i ++)
		{
			if(!vis[i] && map[a.in][i][0] < INF && map[a.in][i][0] + a.x < dist[i][0])
			{
				dist[i][0] = map[a.in][i][0] + a.x ;
				dist[i][1] = map[a.in][i][1] + a.y ;

				b.x = dist[i][0] ;
				b.y = dist[i][1] ;
				b.in = i ;
				Q.push(b) ;
			}
			else if(!vis[i] && map[a.in][i][0] < INF && map[a.in][i][0] + a.x == dist[i][0]
						&& map[a.in][i][1] + a.y < dist[i][1])
			{
				dist[i][1] = map[a.in][i][1] + a.y ;
				b.x = dist[i][0] ;
				b.y = dist[i][1] ;
				b.in = i ;
				Q.push(b) ;
			}
		}
	}
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值