HDU 2066 多源最短路

http://acm.hdu.edu.cn/showproblem.php?pid=2066


用dijistra:

不同一般的题目,这个题目是多个起点 多个终点的;

对不同起点 求最短路,求出不同终点的最小值;

#include <iostream>
#include <cstring>
#include <cstdio>
#define maxn 1003
#define INF 0x3f3f3f3f
using namespace std;

int T,S,D;
int map[maxn][maxn];  //地图 
bool visit[maxn];     //访问标记 
int dis[maxn];        //到起点 距离 
int Scity[maxn];      //起点集 
int Dcity[maxn];      //终点集 

int dijkstra(int source)
{
	memset(visit,false,sizeof(visit));
	for(int i = 1; i <= maxn; i++)
		dis[i] = map[source][i];
	dis[source] = 0;
	
	for(int i = 1; i <= maxn; i++)
	{
		int p = INF,u = -1;
		for(int j = 1; j <= maxn; j++)
		{
			if(!visit[j] && dis[j] < p)
		 	{
	 			p = dis[j];
	 			u = j;
	 		}
		}
		if(u != -1)
		{
			visit[u] = true;
			for(int j = 1; j <= maxn; j++)
			{
				if(!visit[j] && dis[j] > dis[u] + map[u][j]) //Relax()
					dis[j] = dis[u] + map[u][j];
			}
		}
	}
	int mintime = INF;
	for(int i = 1; i <= D; i++)
	{
		mintime = min(mintime, dis[Dcity[i]]);
	}
	return mintime;
}

int main()
{
	int a,b,c;
	while(scanf("%d%d%d",&T,&S,&D)!=EOF)
	{
		memset(map,0x3f,sizeof(map));
		for(int i = 1; i <= T; i++)
		{
			scanf("%d%d%d",&a,&b,&c);
			if(c<map[a][b])
				map[a][b] = map[b][a] = c;
		}
		for(int i = 1; i <= S; i++)
		{
			scanf("%d",&Scity[i]);
		}
		for(int i = 1; i <= D; i++)
		{
			scanf("%d",&Dcity[i]);
		}
		int mintime = INF;
		for(int i = 1; i <= S; i++)
		{
			mintime = min(dijkstra(Scity[i]), mintime);
		}
		printf("%d
",mintime);
	} 
}



用Bellman-Ford :

因为是无向图,所以边数有2*T条,改造成来回的有向图;

可以省略判断是否有负回路的代码;

#include <iostream>
#include <cstdio>
using namespace std;
#define maxn 1000
#define INF 0x3f3f3f3f

int Dcity[maxn];
int Scity[maxn];
int dis[maxn];

struct Edge
{
	int a;
	int b;
	int weight;
}edge[2*maxn];

void relax(int u, int v, int weight)   //松弛 
{
	if(dis[v] > dis[u] + weight)
		dis[v] = dis[u] + weight;
}
 
void InIt(int V, int S)  //初始化 
{
	for(int i = 1; i <= V; i++)    //memset(dis,0x3f,sizeof(dis));
	{
		dis[i] = INF;
	}
	dis[S] = 0;
}

void Bellman_Ford(int V, int E, int S)
{
	InIt(V,S);
	for(int i = 1; i < V; i++)
	{
		for(int j = 1; j <= E; j++)
		{
			relax(edge[j].a,edge[j].b,edge[j].weight);
		}
	}
	//for(int i= 1; i <= E; i++)
	//{
	//	if(dis[edge[i].b] > dis[edge[i].a] + edge[i].weight)
	//		return false;
	//}
	//return true;
}

int main( )
{
	int T,S,D;
	while(scanf("%d%d%d",&T,&S,&D)!=EOF)
	{
		int num = 0;
		for(int i = 1; i <= T; i++)
		{
			scanf("%d%d%d",&edge[i].a,&edge[i].b,&edge[i].weight);   
			edge[i+T].a = edge[i].b;            //因为是无向图 
			edge[i+T].b = edge[i].a;            //所以改成双向有向边 
			edge[i+T].weight = edge[i].weight;  //权值相等 
			num = max(num,max(edge[i].a,edge[i].b)); //求出最大点的标号,节省Bellman_ford时间 
		}
		for(int i = 1; i <= S; i++)
		{
			scanf("%d",&Scity[i]);
		}
		for(int i = 1; i <= D; i++)
		{
			scanf("%d",&Dcity[i]);
		}
		int mintime = INF;
		for(int i = 1; i <= S; i++)
		{
			Bellman_Ford(num,2*T,Scity[i]);
			for(int j = 1; j <= D; j++)
			{
				if(dis[Dcity[j]] < mintime)
					mintime = dis[Dcity[j]];
			}
		}
		printf("%d
",mintime);
	}
	return 0;
}


原文地址:https://www.cnblogs.com/i-fuqiang/p/3189472.html