最短路径问题

最短路径问题

今天这个问题主要和DijkstraFloyd这两种算法有关,第一个用于定点到固定点,第二个可用于任一点到任一点。

先说一下今天遇到的调试的一些问题,在vs里边会出现
错误 1 error C4996: ‘scanf’: This function or variable may be unsafe. Consider using scanf_s instead. To disable deprecation, use _CRT_SECURE_NO_WARNINGS. See online help for details. g:\code\c\test_10_29\test_10_29\main.c 7 1 test_10_29
这样的错误,这是调试器的问题,可以在<stdio.h>头文件前加一行这样的代码,
#define _CRT_SECURE_NO_WARNINGS
当然还有其他解决办法,这里先写这一种。

在说一下这几天的感受吧,感觉算法真的挺难,需要自己好好琢磨,只看教程虽然有用,但还是要理解,不懂的话可以可以先看一些别人的源代码,照着学,看大佬们写的流程,一点一点理解,然后自己敲一遍,不对再比对,找bug,然后调整。重要还是还是要理解。还是要多练,自己这点还是很欠缺的,做一会好像就不太想学了。得慢慢改正。

然后就是今天的题了

在这里插入图片描述在这里插入图片描述这道题可以用今天学的两种算法解,我只用了第一种。第一种比较麻烦一点,主要是还是理解算法思想。这道题基本就是按照算法的基础来的。
代码如下:

/*#pragma once
//#pragma once是一个比较常用的C/C++杂注,
//只要在头文件的最开始加入这条杂注,
//就能够保证头文件只被编译一次*/
/*#include<iostream>//dijsktra
#include<stdio.h>
#include<string.h>
#define INF 0x3f3f3f3f
using namespace std;
void Dijkstra(int n);
int mp[105][105],dis[105];
bool vis[105];
int main()
{
	int a, b, c,N,M;
	while (cin >> N >> M && (N != 0 && M != 0))
	{
		for (int i = 1; i <= 105; i++)
			for(int j = 1;j <= 105;j++)
			    mp[i][j] = INF;
		for (int i = 1; i <= M; i++)
		{
			cin >> a >> b >> c;
			mp[a][b] = mp[b][a] = c;
		}
		Dijkstra(N);
		cout << dis[N] << endl;
	}
	system("pause");
	return 0;
}
void Dijkstra(int n)
{
	int minx, flag = 1;
	for (int i = 1; i <= n; i++)
	{
		dis[i] = mp[1][i];
		vis[i] = true;
	}
	vis[1] = false;
	for (int i = 1; i <= n; i++)
	{
		minx = INF;
		for (int j = 1; j <= n; j++)
		{
			if (vis[j] && dis[j] < minx)//选取到这个位置的最短距离
			{
				flag = j;//记录位置
				minx = dis[j];
			}
		}
		vis[flag] = false;
		if (minx == INF)//如果都访问过,退出循环
			break;
		for (int j = 1; j <= n; j++)
		{
			if (vis[j] && mp[flag][j] + dis[flag] < dis[j])
				dis[j] = mp[flag][j] + dis[flag];
		}
	}
}*/
//Floyd(弗洛伊德算法)
//#define _CRT_SECURE_NO_WARNINGS//除去scanf函数函数安全问题
#include<iostream>
#include<cstdio>
#include<algorithm>
using namespace std;
#define MAX 105
#define INF 1e9
int mp[MAX][MAX];
int n, m, a, b, c;
int main()
{
	while (~scanf("%d%d", &n, &m)) {
		if (n == 0 && m == 0) break;
		for (int i = 1; i <= n; i++)
			for (int j = 1; j <= n; j++)
				mp[i][j] = INF;
		for (int i = 1; i <= m; i++) {
			scanf("%d%d%d", &a, &b, &c);
			mp[a][b] = mp[b][a] = c;
		}
		for (int k = 1; k <= n; k++)
			for (int i = 1; i <= n; i++)
				for (int j = 1; j <= n; j++)
					mp[i][j] = min(mp[i][j], mp[i][k] + mp[k][j]);
		cout << mp[1][n] << endl;
	}
	return 0;
}

在这里插入图片描述在这里插入图片描述
这道题和第一题一样,都是算法的基础运用,但要知道这道题是从0开始,不能只知道套用模板。
代码如下:

#include<iostream>
#include<string.h>
#define INF 0x3f3f3f3f
using namespace std;
bool vis[205];
int mp[205][205],dis[205],N,M;
void Dijkstra(int start);
int main()
{
	int a,b,c;
	while (cin>>N>>M)
	{
		for (int i = 0; i < 205; i++)
			for (int j = 0; j < 205; j++)
			{
				if (i == j)
					mp[i][j] = 0;//当i和j相等时,距离为零
				else
				    mp[i][j] = INF;

			}
		for (int i = 0; i < M; i++)
		{
			cin >> a >> b >> c;
			if(mp[a][b] > c)//这点很重要
			    mp[a][b] = mp[b][a] = c;
		}
		int S, T;
		cin >> S >> T;
		Dijkstra(S);
		if (dis[T] == INF)
			printf("-1\n");
		    //cout << -1 << endl;
		else
			printf("%d\n", dis[T]);
		    //cout << dis[T] << endl;
	}
	return 0;
}
void Dijkstra(int start)
{
	int minx, flag = start;
	for (int i = 0; i < N; i++)
	{
		dis[i] = mp[start][i];
		vis[i] = true;
	}
	vis[flag] = false;
	dis[flag] = 0;
	for (int i = 0; i < N; i++)
	{
		minx = INF;
		for (int j = 0; j < N; j++)
		{
			if (vis[j] && dis[j] < minx)
			{
				minx = dis[j];
				flag = j;
			}
		}
		vis[flag] = false;
		if (minx == INF)
			break;
		for (int j = 0; j < N; j++)
		{
			if (vis[j] && dis[flag] + mp[flag][j] < dis[j])
				dis[j] = dis[flag] + mp[flag][j];
		}
	}
}

在这里插入图片描述这道题加了另一个参数,花费问题,其实就是在模板里边加一个类似于距离的变量,然后最后比较一下,在距离相同时,选择最少的花费。
代码如下:

//#include<iostream>

#define _CRT_SECURE_NO_WARNINGS//该语句必须在#include<stdio.h>之前,否则还会报错
//This function or variable may be unsafe.”警告的解决办法
#include<stdio.h>
#define INF 0x3f3f3f3f

using namespace std;
void Dijkstra(int s);
int n, m, mp[1005][1005], dis[1005], cs[1005],cost [1005][1005];
bool vis[1005];
int main()
{
	while (scanf("%d%d",&n,&m)&&n!=0&&m!=0)
	{
		for(int i = 1;i < 1005;i++)
			for (int j = 1; j < 1005; j++)
			{
				if (i == j)
				{
					mp[i][j] = 0;
					cost[i][j] = 0;
				}
				else
				{
					mp[i][j] = INF;
					cost[i][j] = INF;
				}
			}
		for (int i = 1; i <= m; i++)
		{
			int a, b, d, p;
			scanf("%d%d%d%d", &a, &b, &d, &p);
			//cin >> a >> b >> d >> p;
			if (mp[a][b] > d)
			{
				mp[a][b] = mp[b][a] = d;
				cost[a][b] = cost[b][a] = p;
			}
		}
		int s, t;
		scanf("%d%d", &s, &t);
		//cin >> s >> t;
		Dijkstra(s);
		printf("%d %d\n", dis[t], cs[t]);
		//cout << dis[t] <<" "<< cs[t] << endl;
	}
	return 0;
}
void Dijkstra(int s)
{
	int minx, flag, minc;
	for (int i = 1; i <= n; i++)
	{
		dis[i] = mp[s][i];
		cs[i] = cost[s][i];
		vis[i] = true;
	}
	vis[s] = false;
	dis[s] = 0;
	cs[s] = 0;
	for (int i = 1; i <= n; i++)
	{
		minx = INF;
		minc = INF;
		for (int j = 1; j <= n; j++)
		{
			if (vis[j] && dis[j] < minx)
			{
				minx = dis[j];
				minc = cs[j];
				flag = j;
			}
		}
		vis[flag] = false;
		if (dis[flag] == INF)
			break;
		for (int j = 1; j <= n; j++)
		{
			if (vis[j] && dis[j] > dis[flag] + mp[flag][j])
			{
				dis[j] = dis[flag] + mp[flag][j];
				cs[j] = cs[flag] + cost[flag][j];
			}
			else if (vis[j] && dis[j] == dis[flag] + mp[flag][j])
				cs[j] = cs[flag] + cost[flag][j];
		}
	}
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值