【最短路】Til The Cows Come home(裸题)

题意就是给你一张图,让你找从N到1的最短路 坑:可能有重边

Sample Input
5 5
1 2 20
2 3 30
3 4 20
4 5 20
1 5 100
Sample Output
90


参考:https://blog.csdn.net/major_zhang/article/details/72519233

自己写的简单Dijkstra:

#include <stdio.h>
#include <algorithm>
#include <vector>
#include <iostream>
#include <string.h>
#define MAXN 2008

const int INF = 0x3f3f3f3f;
int dis[MAXN];   //点i到点N(起点)的距离
int vis[MAXN];
int Map[MAXN][MAXN];
using namespace std;

int main()
{
	int T, N;
	while (scanf("%d %d", &T, &N) != EOF)
	{
		memset(Map, INF, sizeof(Map));
		memset(dis, INF, sizeof(dis));

		dis[N] = 0;
		vis[N] = 1;
		while (T--)
		{
			int a, b, d;
			scanf("%d %d %d", &a, &b, &d);
			if (d < Map[a][b])
				Map[a][b] = Map[b][a] = d;
		}
		for (int i = 1; i < N; ++i)
		{
			if (Map[i][N] != INF) dis[i] = Map[i][N];
		}
		for (int i = 1; i < N; ++i)
		{
			int minv = INF, minj = -1;
			for (int j = 1; j < N; ++j)
			{
				if (!vis[j] && dis[j] != INF && dis[j] < minv)
				{
					minv = dis[j];
					minj = j;
				}
			}
			vis[minj] = 1;
			for (int j = 1; j < N; ++j)
			{
				if (j == minj) continue;
				if (!vis[j] && Map[j][minj] != INF && Map[j][minj] + dis[minj] < dis[j])
				{
					dis[j] = Map[j][minj] + dis[minj];
				}
			}
		}
		printf("%d\n", dis[1]);
	}
    return 0;
}

参考 照抄的堆优化Dijkstra:
#include <iostream>
#include <cstdio>
#include <algorithm>
#include <vector>
#include <queue>
#include <cstring>
#define MAXN 10008
#define pb push_back
#define INF 0x3f3f3f3f
using namespace std;

struct Node
{
	int n;
	int d;
	Node() {}
	Node(int a, int b) { n = a; d = b; }
	bool operator< (const Node x) const
	{
		return d > x.d;
	}
};

priority_queue<Node> que;
vector<Node> Map[MAXN];
int dis[MAXN];
int T, N;
void Dijkstra(int start)
{
	memset(dis, INF, sizeof(dis));
	dis[N] = 0;
	que.push(Node(start, dis[start]));
	while (!que.empty())
	{
		Node x = que.top();
		que.pop();
		int LEN = Map[x.n].size();
		for (int i = 0; i < LEN; ++i)
		{
			Node now = Map[x.n][i];
			if (dis[now.n] > x.d + now.d)
			{
				dis[now.n] = x.d + now.d;
				que.push(Node(now.n, dis[now.n]));
			}
		}
	}
	
}

int main()
{

	scanf("%d %d", &T, &N);
	for (int i = 0; i < T; ++i)
	{
		int a, b, d;
		scanf("%d %d %d", &a, &b, &d);
		Map[a].pb(Node(b, d));
		Map[b].pb(Node(a, d));
	}
	Dijkstra(N);
	printf("%d\n", dis[1]);
	return 0;
}

Floyd:O(n^3)不T才有鬼了 不放了

SPFA:牛逼 好懂又跑得快

#include <cstdio>
#include <iostream>
#include <queue>
#include <algorithm>
#include <cstring>
#include <cmath>
#define INF 0x3f3f3f3f
#define MAXN 1008
using namespace std;

int Map[MAXN][MAXN];
int dis[MAXN];
int inque[MAXN];
queue<int> que;    //存放待松弛的顶点序号


int T, N;

void SPFA(int s)
{
	que.push(s);
	dis[s] = 0;
	inque[s] = 1;
	while (!que.empty())
	{
		int n = que.front();
		que.pop();
		inque[n] = 0;
		for (int i = 1; i <= N; ++i)
		{
			if (i == n) continue;
			if (dis[i] > dis[n] + Map[n][i] && Map[n][i] != INF)
			{
				dis[i] = dis[n] + Map[n][i];
				if (!inque[i]) que.push(i);
			}
		}
	}
}

int main()
{
	scanf("%d %d", &T, &N);
	memset(Map, INF, sizeof(Map));
	memset(dis, INF, sizeof(dis));
	while (T--)
	{
		int a, b, d;
		scanf("%d %d %d", &a, &b, &d);
		Map[b][a] = Map[a][b] = min(Map[a][b], d);
	}
	SPFA(N);
	printf("%d\n", dis[1]);
	return 0;
}

Bellman-Ford

解决负环的

#include <cstdio>
#include <algorithm>
#include <cstring>
#include <iostream>
#define INF 0x3f3f3f3f
#define MAXN 2008
#define MAXM 4008
using namespace std;

struct Line
{
	int x;
	int y;
	int d;
};

Line Map[MAXM * 2];
int dis[MAXN];
int T, N;

void printdis()
{
	for (int i = 1; i <= N; ++i)
	{
		printf("%d  ", dis[i]);
	}
	printf("\n");
}
bool BellmanFord(int src)
{
	dis[src] = 0;
	for (int i = 1; i < N; ++i)
	{
		for (int l = 1; l <= 2 * T; ++l)
		{
			if (dis[Map[l].y] > dis[Map[l].x] + Map[l].d)
			{
				dis[Map[l].y] = dis[Map[l].x] + Map[l].d;
			}
		}
		//printdis();
	}
	for (int l = 1; l <= 2 * T; ++l)
	{
		if (dis[Map[l].y] > dis[Map[l].x] + Map[l].d)
		{
			return false;
		}
	}
	return true;
}

int main()
{
	memset(dis, INF, sizeof(dis));
	scanf("%d %d", &T, &N);
	for (int i = 1; i <= T; ++i)
	{
		Line tmp;
		scanf("%d %d %d", &tmp.x, &tmp.y, &tmp.d);
		Map[i] = tmp;
		Line tmp1 = tmp;
		swap(tmp1.x, tmp1.y);
		Map[i + T] = tmp1;
	}
	if (BellmanFord(1))
	{
		printf("%d\n", dis[N]);
	}
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值