floyd模板(基于poj1847)

例1:

题意:

萨格勒布的电车网络由许多交叉路口和连接其中一些的铁路组成。在每个交叉路口都有一个开关,指向从交叉口出来的一个轨道。当有轨电车进入交叉路口时,它只能沿开关指向的方向离开。如果驾驶员想要采取其他方式,他/她必须手动更换开关。 
当驾驶员从交叉路口A开车到交叉路口B时,他/她试图选择将最小化他/她必须手动更换开关的次数的路线。 

编写一个程序,计算从交叉路口A到交叉路口B所需的最小开关变化次数。 

Input:

输入的第一行包含整数N,A和B,由单个空白字符分隔,2 <= N <= 100,1 <= A,B <= N,N是网络中的交叉点数,以及交叉点从1到N编号。 
以下N行中的每一行包含由单个空白字符分隔的整数序列。第i行中的第一个数字Ki(0 <= Ki <= N-1)表示从第i个交叉点出来的轨道数。下一个Ki数字表示直接连接到第i个交叉点的交叉点。第i个交叉点中的交换点最初指向列出的第一个交叉点的方向。 

Output:

输出的第一行也是唯一一行应包含目标最小数。如果没有从A到B的路由,则该行应包含整数“-1”。

样例输入:

3 2 1

2 2 3

2 3 1

2 1 2

样例输出:

0

代码如下:

#include<cstdio>
#include<iostream>
#include<algorithm>
#include<queue>
#include<cstring>
#include<functional>//greater/less的头文件
using namespace std;
const int maxn = 105;
const int Max = 1e7 + 10;
int a[maxn][maxn];
int n, A, B;
int main()
{
	cin >> n >> A >> B;
	for (int i = 1; i <= n; i++) {		//初始化
		for (int j = 1; j <= n; j++) {
			if (i == j)a[i][j] = 0;
			else a[i][j] = Max;
		}
	}
	int k, t;
	for (int i = 1; i <= n; i++) {		//赋值
		cin >> k;
		for (int j = 1; j <= k; j++) {
			cin >> t;
			if (j == 1)
				a[i][t] = 0;
			else
				a[i][t] = 1;
		}
	}
	for(int k=1;k<=n;k++)
		for(int i=1;i<=n;i++)
			for (int j = 1; j <= n; j++) {
				if (a[i][j] > a[i][k] + a[k][j])
					a[i][j] = a[i][k] + a[k][j];
			}
	if (a[A][B] == Max)
		cout << -1 << endl;
	else
		cout << a[A][B] << endl;
	return 0;
}

补:

1、如果要判断负循环,只需加一句:

     if(a[i][i]<0)

2、在算法中偶尔初始值会很大,所以要消除加法溢出问题

     if(d[i][k]<INF&&d[k][j]<INF) 

3、防止如果有负权边出现影响结果

     if(p[now][i] == Max)continue;

4、防止重边

     p[a][b] = p[b][a] = min(p[a][b], w);

猜你喜欢

转载自blog.csdn.net/zsnowwolfy/article/details/81877027