hdu2680Choose the best route

本文解析了 HDU 2680 题目,该题涉及多个起点到单一终点的有向单源最短路径问题。通过引入虚拟起点并采用 Dijkstra 算法进行求解。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

1.题目链接:

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

 

2.思路 :

       这道题目是多个起点,一个终点,属于有向单源最短路问题。可以假设一个虚拟的起点,然后将虚拟起点到没有起点的距离设为0,这样就可以用dijkstra反向建图。

 

3.参考代码:

 

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

#define inf 0xffff

int n,m,s;
int edge[1100][1100];   ///图的邻接矩阵
int dis[1100];   ///存放距离的
int vis[1100];   ///标记是否访问过

void dijkstra(int v){   ///dijkstra算法
	
	int i,j;   ///循环变量
	int k=0;   ///标记,一定要记得先赋初始值为0
	
	memset(vis,0,sizeof(vis));   ///初始化为都0,表示都没有访问过
	
	for(i=1;i<=n;i++)
		dis[i]=edge[v][i];   ///
	
	vis[v]=1;   ///标记起点为已访问过的
	dis[v]=0;   ///本身到本身的距离为0
	
	for(i=1;i<=n;i++)
	{
		int min=inf;
		
		for(j=1;j<=n;j++)   ///遍历所有的点
		{
			if(dis[j]<min && !vis[j])
			{
				min=dis[j];
				k=j;
			}			
		}
		
		if(min==inf)   ///如果没有找到最小值,就退出
			break;
		
		vis[k]=1;   ///标记已访问过
		
		for(j=1;j<=n;j++)   ///遍历所有的点
		{
			if(dis[j]>dis[k]+edge[k][j] && !vis[j])
				dis[j]=dis[k]+edge[k][j];
		}
	}
	
	if(dis[s]==inf)
		printf("-1\n");
	else
		printf("%d\n",dis[s]);
}

int main()
{
	int i,j;   ///循环变量
	int t,r;
	int u,v,w;   ///两个站点,以及它们之间的距离
	
	while(~scanf("%d %d %d",&n,&m,&s))
	{
		for(i=0;i<=n;i++)   ///注意这里的下标是从0开始的,从1不行
		{
			for(j=0;j<=n;j++)   ///注意这里的下标是从0开始的,从1不行
			{
				if(i==j)
					edge[i][j]=0;
				else
					edge[i][j]=edge[j][i]=inf;
			}
		}
		
		//memset(edge,inf,sizeof(edge));  ///初始化不能这样做,否则得不到正确答案 

		while(m--)
		{
			scanf("%d %d %d",&u,&v,&w);

			if(edge[u][v]>w)   ///不要忘记消除重边的情况
				edge[u][v]=w;
			///edge[u][v]=edge[v][u]=w;   ///不能这么写,不然会WA
		}
		
		scanf("%d",&t);
		
		while(t--)
		{
			scanf("%d",&r);
			edge[0][r]=0;   ///所设的虚拟起点到没有顶点的距离都为0
		}
		
		dijkstra(0);   ///从所设的虚拟起点开始
	}
	
	return 0;
}


 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值