1. 程式人生 > >HDU 3790 最短路徑問題

HDU 3790 最短路徑問題

EEEE.

貌似但凡涉及到最短路徑都會涉及到重邊。

重邊的更新也要涉及到權的優先順序。

這道題目權值更新

(1)相同點對之間路徑重複輸入,取路徑最短的 那一條,更新距離和花費

(2)相同點對之間路徑重複輸入,路徑長度相等,取花費少的那一條。

此外這題典型Dijkstra演算法O(N^{2})輕鬆過.

#include <cstdio>
#include <map>
#include <vector>
using namespace std;
const int INF=1<<29;
struct Node{
	bool  know;
	vector <int> adj;	
}g[1005];
int D[1005][1005];
int P[1005][1005];
void Dijkstra(int s,int t,int n)
{
	int v;
	int dist[1005];
	int pfee[1005];
	for (int i=1;i<=n+1;i++)
	{
		dist[i]=INF;
		pfee[i]=INF;
		g[i].know=false;
	}
	vector <int> :: iterator it;
	dist[s]=0;
	pfee[s]=0;
	for (;;)
	{
		v=n+1;
		for (int i=1;i<=n;i++)
		{
			if (g[i].know==false && dist[i]<dist[v])
				v=i;
		}
		if (v==n+1)
			break;
		g[v].know=true;
		for (it=g[v].adj.begin();it!=g[v].adj.end();it++)
		{
			//取路徑最短的;
			//路徑長度相同,取花費少的 
			if (dist[*it]>dist[v]+D[v][*it] || (dist[*it]==dist[v]+D[v][*it] && pfee[*it]>pfee[v]+P[v][*it]))
			{
				dist[*it]=dist[v]+D[v][*it] ;
				pfee[*it]=pfee[v]+P[v][*it];
			}
		}
	}
	printf ("%d %d\n",dist[t],pfee[t]);
}
int main()
{
	int n,m,a,b,s,t,d,p;
	while (~scanf ("%d%d",&n,&m)&&(n+m))
	{
		for (int i=1;i<=n;i++)
		{
			g[i].adj.clear();
			for (int j=1;j<=n;j++)
			{
				D[i][j]=INF;
				P[i][j]=INF;
			}
		}
		for (int i=1;i<=m;i++)
		{
			scanf ("%d%d%d%d",&a,&b,&d,&p);
			if (D[a][b]==INF)
			{
				D[b][a]=D[a][b]=d;
				P[b][a]=P[a][b]=p;	
				g[a].adj.push_back(b);
				g[b].adj.push_back(a);		
			}
			else
			{
				if (D[a][b]>d)
				{
					D[b][a]=D[a][b]=d;
					P[b][a]=P[a][b]=p;	
				}
				else if (D[a][b]==d && P[a][b]>p)
				{
					D[b][a]=D[a][b]=d;
					P[b][a]=P[a][b]=p;	
				}
			}
		}
		scanf ("%d%d",&s,&t);
		Dijkstra(s,t,n);
	}
	return 0;
}