p121和123 dijkstra等会再打

本文介绍了解决单源最短路径问题的Dijkstra算法,并通过两个示例程序详细展示了算法的具体实现过程。包括如何使用邻接表存储图结构、初始化距离数组和标记数组,以及核心的迭代更新步骤。

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

//dijkstra 是解决单源最短路问题的,其复杂度低于floyd算法,但是代码量比较大

//下面这个是p121

//一遍过,我就是牛逼//这个是第一个dijkstra
//思路基本上是初始化vector edge,输入vector,初始化dis和mark,置第一个dis和mark和newp
//对剩下n-1个vector进行1.利用此时的newp更新 2.求得当前dis最小的newp,注意这个newp既不在集合k里面又不是不能到达的
#include <stdio.h>
#include <vector>
using namespace std;

int dis[101];
bool mark[101];

struct E{
	int next;
	int c;
};

vector<E> edge[101]; 

int main()
{
	int n,m;
	while(scanf("%d %d",&n,&m)!=EOF)
	{
		if(n==0 && m==0)break;
		
		for(int i=1;i<=n;i++)edge[i].clear();
		
		for(int i=1;i<=m;i++)
		{
			int a,b,c;
			scanf("%d %d %d",&a,&b,&c);
			E tmp;
			tmp.next=a;
			tmp.c=c;
			edge[b].push_back(tmp);
			tmp.next=b;
			edge[a].push_back(tmp);
		}
		for(int i=1;i<=n;i++)
		{
			dis[i]=-1;
			mark[i]=false;
		}
		dis[1]=0;
		mark[1]=true;
		int newp = 1;//第一个newp就是源! 
		for(int i=1;i<n;i++)
		{
			for(int j=0;j<edge[newp].size();j++)
			{
				int t=edge[newp][j].next;
				int co=edge[newp][j].c;//不太清楚能不能重复定义,尽量不要吧 
				if(mark[t]==true)continue;
				if(dis[t]==-1 || dis[t]>dis[newp]+co)
					dis[t]=dis[newp]+co;	
			}
			int min=123123123;
			for(int j=1;j<=n;j++)
			{
				if(mark[j]==true)continue;
				if(dis[j]==-1)continue;
				if(min>dis[j])
				{
					min=dis[j];
					newp=j; 
				}
			}
			mark[newp]=true;
		}
		printf("%d\n",dis[n]);
	}
	return 0;
 } 

P123

#include <stdio.h>//总结:忘了写mark[newp]=true;还有很多for里面的i是没用的
#include <vector>

using namespace std;

int dis[1001];
bool mark[1001];
int cost[1001];

struct E{//注意这个邻接表的边是next和cost 
	int next;
	int c;
	int co;
};

vector<E> edge[1001];

int main()
{
	int n,m;
	while(scanf("%d %d",&n,&m)!=EOF)
	{
		if(n==0 &&m==0)break;
		for(int i=1;i<=n;i++)edge[i].clear();
		for(int i=1;i<=m;i++)//这个i用于while的
		{
			int a,b,c,co;
			scanf("%d %d %d %d",&a,&b,&c,&co);
			E tmp;
			tmp.next=a;
			tmp.c=c;
			tmp.co=co; 
			edge[b].push_back(tmp);
			tmp.next=b;
			edge[a].push_back(tmp);
		}
		int s,t;
		scanf("%d %d",&s,&t);
		for(int i=1;i<=n;i++)
		{
			dis[i]=-1;
			mark[i]=false;
			cost[i]=123123123;//这个有必要初始化吗。。。可以初始化也可以不初始化,这个逻辑很复杂就不解释了,知道就好
		}
		
		dis[s]=0;
		mark[s]=true;
		cost[s]=0;
		int newp=s;
		
		for(int i=1;i<n;i++)//这个i只是用来循环的//可以改为while
		{
			
			for(int j=0;j<edge[newp].size();j++)
			{
				int tt=edge[newp][j].next;//这个是 edge[newp][j].next不是edge[i][j].next 
				int c=edge[newp][j].c;
				int co=edge[newp][j].co;
				if(mark[tt]==true)continue;
				if(dis[tt]==-1||dis[tt]>dis[newp]+c||(dis[tt]==dis[newp]+c && cost[tt]>cost[newp]+co))
				{
					dis[tt]=dis[newp]+c;
					cost[tt]=cost[newp]+co;
				}
			}
			int min=123123123;
			for(int j=1;j<=n;j++)
			{
				if(mark[j]==true)continue;
				if(dis[j]==-1)continue;
				if(min>dis[j])
				{
					min=dis[j];
					newp=j;
				
				}
			}
			mark[newp]=true;//居然忘了这个天哪。。
		}
		printf("%d %d\n",dis[t],cost[t]);
	}
	return 0;
 } 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值