算法学习笔记五:最短路径

题目描述
卫斯理小说经常提及外星人,比如蓝血人。 在土星星球有很多城市,每个城市之间有一条或多条飞行通道, 但是并不是所有的路都是很安全的,每一条路有一个安全系数 s,s 是在 0和1 间的实数 (包括 0 , 1) ,一条从 u 到 v 的通道 P 的安全度为 Safe§ = s(e1)*s(e2)…s(ek) e1,e2,ek是P 上的边 ,现在蓝血人想出去旅游,面对这这么多的路,他想找一条最安全的路。但是蓝血人的数学不好,想请你帮忙 _
输入
输入包括多个测试实例,每个实例包括:
第一行: 一个整数 n。 n 表示城市的个数 n<=1000;
接着是一个 n
n 的矩阵表示两个城市之间的安全系数, (0可以理解为那两个城市之间没有直接的通道 )。
接着是一个整数m (m<=100)表示若干个蓝血人要旅游的路线 ,下面每行有两个数字,表示蓝血人所在的城市和要去的城市。
输出
如果蓝血人无法达到他的目的地,输出 “What a pity!” ,
其他的输出这两个城市之间的最安全道路的安全系数,保留三位小数。
样例输入
3
1 0.5 0.5
0.5 1 0.4
0.5 0.4 1
3
1 2
2 3
1 3
样例输出
0.500
0.400
0.500

解法一 :prim算法

//dijkstra 
#include
#include
#include
using namespace std;
//#define INF 1000000000
#define maxv 1010
bool vis[maxv];
double map[maxv][maxv];
double d[maxv];//顶点到各点的安全系数
int n;
int dijkstra(int x,int y)
{
	memset(vis,false,sizeof(vis));
	fill(d,d+maxv,0);
	d[x]=1;//起点到自身安全系数为1
	if(x==y)
		return 1;
	for(int i=0;i<n;i++)
	{
		int u=-1;
		double maxn=0;//此题是求安全系数最大,所以取最大值 
		for(int j=0;j<n;j++)
		{
			if(vis[j]==false&&d[j]>maxn)
			{
				u=j;
				maxn=d[j];
			}
		}
		if(u==-1)//起点与剩下的点不连通 
			return -1;
		if(u==y)//找到到达终点的最短路径 
			return 1;
		vis[u]=true;
		for(int v=0;v<n;v++)
		{
			if(vis[v]==false&&map[v][u]!=0&&d[v]<d[u]*map[v][u])
				d[v]=d[u]*map[v][u];
		}	
	 } 
}
int main()
{
	while(cin>>n)
	{
		int i,j,m,x,y;
		fill(map[0],map[0]+maxv*maxv,0);//初始化0表示没边 
		for(i=0;i<n;i++)
			for(j=0;j<n;j++)
				cin>>map[i][j];
		cin>>m;
		for(i=0;i<m;i++)
		{
			cin>>x>>y;
			int ans;
			ans=dijkstra(x-1,y-1);
			if(ans==-1)
				cout<<"What a pity!"<<endl;
			else
				printf("%.3lf\n",d[y-1]);
		}			
	}
	return 0;
}

解法二:floyd算法

//floyd 
#include
#include
using namespace std;
const int maxv=1010;
double dis[maxv][maxv];//存放安全路径 
int n;
void floyd()
{
	for(int k=0;k<n;k++)
		for(int i=0;i<n;i++)
			for(int j=0;j<n;j++)
			{
				if(dis[i][k]!=0&&dis[k][j]!=0&&dis[i][k]*dis[k][j]>dis[i][j])
					 dis[i][j]=dis[i][k]*dis[k][j];
			}
}
int main()
{
	while(cin>>n)
	{
		int i,j,m,x,y;
		fill(dis[0],dis[0]+maxv*maxv,0);
		for(i=0;i<n;i++)
			for(j=0;j<n;j++)
				cin>>dis[i][j];
		floyd();
		cin>>m;
		for(i=0;i<m;i++)
		{
			cin>>x>>y;
			if(dis[x-1][y-1]==0)
				cout<<"What a pity!"<<endl;
			else
				printf("%.3lf\n",dis[x-1][y-1]);
		}			
	}
	return 0;
}

你可能感兴趣的:(算法题)