模板--最短路(简单)

POJ 1847为例。

/*
有N个路口,计算从a路口到b路口的最短转弯数。
对于每一个路口,有t个分叉口,第一个分叉口是直行,也就是不用转弯
剩下的t-1个路口都需要转弯一次。
*/


/************Dijkstra***************/

#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <cmath>
#include <queue>
#include <stack>
#include <vector>
using namespace std;

const int maxn = 110;
const int maxm = 10010;
const int INF = 0x3f3f3f3f;
 
int map[maxn][maxn], n, a, b, t, p;

int Dijkstra(int s, int e)//212K 47MS
{
	int vis[maxn], dis[maxn];
	memset(vis, 0, sizeof(vis));
	for (int i = 1; i <= n; i++)
		dis[i] = map[s][i];
	vis[s] = 1;
	for (int i = 0; i < n; i++)
	{
		int k = -1;
		int tmp = INF;
		for (int j = 1; j <= n;j++)
			if (!vis[j] && dis[j] < tmp)
			{
				k = j;
				tmp = dis[j];
			}
		if (k == -1) break;
		vis[k] = 1;
		for (int j = 1; j <= n; j++)
			if (!vis[j] && map[k][j] < INF)
				dis[j] = min(dis[j], dis[k] + map[k][j]);
	}
	return dis[e];
}

int main()
{
#ifdef LOCAL
	freopen("in.txt", "r", stdin);
	//freopen("out.txt", "w", stdout);
#endif 
	while (~scanf("%d%d%d", &n, &a, &b))
	{
		for (int i = 1; i <= n; i++)
			for (int j = 1; j <= n; j++)
				if (i == j) map[i][j] = 0;
				else map[i][j] = INF;
		for (int i = 1; i <= n; i++)
		{
			scanf("%d", &t);
			for (int j = 1; j <= t; j++)
			{
				scanf("%d", &p);
				if (j == 1) map[i][p] = 0;
				else map[i][p] = 1;
			}
		}
		int ans = Dijkstra(a, b);
		if (ans == INF) ans = -1;
		printf("%d\n", ans);
	}
	return 0;
}


/********Dijkstra+Heap*******/


#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <cmath>
#include <queue>
#include <stack>
#include <vector>
using namespace std;

const int maxn = 110;
const int maxm = 10010;
const int INF = 0x3f3f3f3f;

struct Edge {
	int v, w, next;
}edge[maxm];

int vis[maxn], head[maxn];
int n, a, b, t, p, tot;

void AddEdge(int from, int to, int dist, int k)
{
	edge[k].v = to;
	edge[k].w = dist;
	edge[k].next = head[from];
	head[from] = k;
}

struct HeapNode {
	int dist, u;
	bool operator < (const HeapNode& rhs) const {
		return dist > rhs.dist;
	}
}dis[maxn];

int Dijkstra_Heap(int s,int e)//184K 0MS
{
	priority_queue<HeapNode> q;
	while (!q.empty()) q.pop();
	for (int i = 1; i <= n; i++)//结点标号:1--n
	{
		dis[i].u = i;
		dis[i].dist = INF;
	}
	dis[s].dist = 0;
	memset(vis, 0, sizeof(vis));
	q.push(dis[s]);
	while (!q.empty()) {
		HeapNode x = q.top();
		q.pop();
		int u = x.u;
		if (vis[u]) continue;
		vis[u] = 1;
		for (int i = head[u]; i != -1; i = edge[i].next) {
			int v = edge[i].v;
			int w = edge[i].w;
			if (dis[v].dist > dis[u].dist + w) {
				dis[v].dist = dis[u].dist + w;
				q.push(dis[v]);
			}
		}
	}
	return dis[e].dist;
}

int main()
{
#ifdef LOCAL 
	freopen("in.txt", "r", stdin);
	//freopen("out.txt", "w", stdout);
#endif 
	while (~scanf("%d%d%d", &n, &a, &b))
	{
		memset(head, -1, sizeof(head));
		tot = -1;
		for (int i = 1; i <= n; i++)
		{
			scanf("%d", &t);
			for (int j = 1; j <= t; j++) {
				tot++;
				scanf("%d", &p);
				if (j == 1) AddEdge(i, p, 0, tot);
				else AddEdge(i, p, 1, tot);
			}
		}
		int ans = Dijkstra_Heap(a, b);
		if (ans == INF) ans = -1;
		printf("%d\n", ans);
	}
	return 0;
}

/**********Floyd***********/


#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <cmath>
#include <queue>
#include <stack>
#include <vector>
using namespace std;

const int maxn = 110;
const int maxm = 10010;
const int INF = 0x3f3f3f3f;
 
int map[maxn][maxn], n, a, b, t, p;

int floyd(int s,int e)//212K 16MS
{
	for (int k = 1; k <= n; k++)
		for (int i = 1; i <= n; i++)
			for (int j = 1; j <= n; j++)
				map[i][j] = min(map[i][j], map[i][k] + map[k][j]);
	return map[s][e];
}

int main()
{
#ifdef LOCAL
	freopen("in.txt", "r", stdin);
	//freopen("out.txt", "w", stdout);
#endif 
	while (~scanf("%d%d%d", &n, &a, &b))
	{
		for (int i = 1; i <= n; i++)
			for (int j = 1; j <= n; j++)
				if (i == j) map[i][j] = 0;
				else map[i][j] = INF;
		for (int i = 1; i <= n; i++)
		{
			scanf("%d", &t);
			for (int j = 1; j <= t; j++)
			{
				scanf("%d", &p);
				if (j == 1) map[i][p] = 0;
				else map[i][p] = 1;
			}
		}
		int ans=floyd(a,b);
		if (ans == INF) ans = -1;
		printf("%d\n", ans);
	}
	return 0;
}



/**************Bellman_Ford*********************/

#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <cmath>
#include <queue>
#include <stack>
#include <vector>
using namespace std;

const int maxn = 110;
const int maxm = 10010;
const int INF = 0x3f3f3f3f;
 
int n, a, b, uu, vv, ww, t, tot, p;
int dis[maxn];

struct Edge {
	int u, v, w;
}edge[maxm];

int Bellman_Ford(int s, int e)//172K  0MS
{
	for (int i = 1; i <= n; i++)
	{
		if (i == s) dis[i] = 0;
		else dis[i] = INF;
	}
	for (int i = 0; i < n - 1; i++)
		for (int j = 0; j <= tot; j++)
		{
			int x = edge[j].u;
			int y = edge[j].v;
			int z = edge[j].w;
			dis[y] = min(dis[y], dis[x] + z);
		}
	return dis[e];
}

int main()
{
#ifdef LOCAL
	freopen("in.txt", "r", stdin);
	//freopen("out.txt", "w", stdout);
#endif 
	while (~scanf("%d%d%d", &n, &a, &b))
	{
		tot = -1;
		for (int i = 1; i <= n; i++)
		{
			scanf("%d", &t);
			for (int j = 1; j <= t; j++)
			{
				++tot;
				scanf("%d", &p);
				edge[tot].u = i;
				edge[tot].v = p;
				if (j == 1) edge[tot].w = 0;
				else edge[tot].w = 1;
			}
		}
		int ans = Bellman_Ford(a, b);
		if (ans == INF) ans = -1;
		printf("%d\n", ans);
	}
	return 0;
}


/***********SPFA+QUEUE***********/
/***********SPFA+STACK***********/

#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <cmath>
#include <queue>
#include <stack>
#include <vector>
using namespace std;

const int maxn = 110;
const int maxm = 10010;
const int INF = 0x3f3f3f3f;

int dis[maxn], head[maxn], vis[maxn];
int n, a, b, t, p, tot;

struct Edge {
	int v, w, next;
}edge[maxm];

void AddEdge(int u, int v, int w, int k)
{
	edge[k].v = v;
	edge[k].w = w;
	edge[k].next = head[u];
	head[u] = k;
}

int SPFA_QUEUE(int s, int e)//队列实现 184K 16MS
{
	queue<int> q;
	if (!q.empty()) q.pop();
	for (int i = 1; i <= n; i++)
	{
		if (i == s) dis[i] = 0;
		else dis[i] = INF;
	}
	memset(vis, 0, sizeof(vis));
	vis[s] = 1;
	q.push(s);
	while (!q.empty())
	{
		int uu = q.front();
		q.pop();
		vis[uu] = 0;
		for (int i = head[uu]; i != -1; i = edge[i].next)
		{
			int vv = edge[i].v;
			int ww = edge[i].w;
			if (dis[uu] < INF && dis[vv] > dis[uu] + ww)
			{
				dis[vv] = dis[uu] + ww;
				if (!vis[vv])
				{
					vis[vv] = 1;
					q.push(vv);
				}
			}
		}
	}
	return dis[e];
}

int SPFA_STACK(int s, int e)//栈实现 184K 0MS
{
	stack<int> q;
	if (!q.empty()) q.pop();
	for (int i = 1; i <= n; i++)
	{
		if (i == s) dis[i] = 0;
		else dis[i] = INF;
	}
	memset(vis, 0, sizeof(vis));
	vis[s] = 1;
	q.push(s);
	while (!q.empty())
	{
		int uu = q.top();
		q.pop();
		vis[uu] = 0;
		for (int i = head[uu]; i != -1; i = edge[i].next)
		{
			int vv = edge[i].v;
			int ww = edge[i].w;
			if (dis[uu] < INF && dis[vv] > dis[uu] + ww)
			{
				dis[vv] = dis[uu] + ww;
				if (!vis[vv])
				{
					vis[vv] = 1;
					q.push(vv);
				}
			}
		}
	}
	return dis[e];
}

int main()
{
#ifdef LOCAL 
	freopen("in.txt", "r", stdin);
	//freopen("out.txt", "w", stdout);
#endif 
	while (~scanf("%d%d%d", &n, &a, &b))
	{
		tot = -1;
		memset(head, -1, sizeof(head));
		for (int i = 1; i <= n; i++)
		{
			scanf("%d", &t);
			for (int j = 1; j <= t; j++)
			{
				++tot;
				scanf("%d", &p);
				if (j == 1) AddEdge(i, p, 0, tot);
				else AddEdge(i, p, 1, tot);
			}
		}
		//int ans = SPFA_QUEUE(a, b);
		int ans = SPFA_STACK(a, b);
		if (ans == INF) ans = -1;
		printf("%d\n", ans);
	}
	return 0;
}





评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值