find the safest road HDU杭電1596【Dijkstra‖SPFA】

3428 ワード

http://acm.hdu.edu.cn/showproblem.php?pid=1596
Problem Description
XX星には多くの都市があり、各都市の間には1つ以上の飛行通路がありますが、すべての道が安全であるわけではありません.各道路には安全係数sがあり、sは0と1の間の実数(0,1を含む)で、uからvまでの通路Pの安全度はSafe(P)=s(e 1)*s(e 2)…*s(ek)e 1、e 2、ekはPの端で、今8600は旅行に行きたいと思っています.このような多くの道に直面して、彼は最も安全な道を探したいと思っています.でも8600は数学が苦手なので手伝ってもらいたいです^^;
 
Input
入力には、次のような複数のテストインスタンスが含まれます.
1行目:n.nは都市の個数n<=1000を表す.
次にn*nの行列が2つの都市間の安全係数を表す(0はその2つの都市間に直接的な通路がないと理解できる)
続いてQつの8600の旅行するルートで、1行ごとに2つの数字があって、8600の所在する都市と行く都市を表します
 
Output
86が目的地に達しなければ「What a pity!」と出力し、
他の出力の2つの都市間の最も安全な道路の安全係数は、3桁の小数を保持します.
 
Sample Input

   
   
   
   
3 1 0.5 0.5 0.5 1 0.4 0.5 0.4 1 3 1 2 2 3 1 3

 
Sample Output

   
   
   
   
0.500 0.400 0.500

 
SPFA
#include <cstdio>
#include <cstring>
#include <queue>
#define MAXN 1100
using namespace std;

double map[MAXN][MAXN];
int vis[MAXN];//          
int num;
double low[MAXN];//      
int s, e;
int M, N;
void SPFA()
{
	int i, j;
	queue<int> Q;
	memset(low, 0, sizeof(low)); 
	memset(vis, 0, sizeof(vis));	
	vis[s] = 1;
	low[s] = 1;
	Q.push(s);
	while(!Q.empty())
	{
		int u = Q.front();
		Q.pop();
		vis[u] = 0;//    ,       0 
		for(i = 1; i <= N; ++i)
		{
			
			if(low[i] < low[u] * map[u][i])
			{
				low[i] = low[u] * map[u][i];
				if(!vis[i])				 
			 	{
			 		vis[i]=1;
			 		Q.push(i);
			 	}
			}
		}
	}
	if(low[e] == 0) printf("What a pity!
"); else printf("%.3f
",low[e]); } int main() { int u, v; double w; while(~scanf("%d", &N)) { num=0; for(int i=1 ;i <= N; ++i) { for(int j=1; j <= N; ++j) { scanf("%lf",&w); map[i][j]=w; } } scanf("%d", &M); while(M--) { scanf("%d%d", &s, &e); SPFA(); } } return 0; }

Dijkstra
#include<stdio.h>
#include<string.h>
double map[1010][1010];
double dis[1010];
bool used[1010];
int n;
int i,j;
void dijkstra(int u)
{
	memset(used,0,sizeof(used));
	for(i=1;i<=n;++i)
		dis[i]=0;

	int pos=u;
	for(i=1;i<=n;++i)//    dis   
	{
		dis[i]=map[u][i];
	}
	dis[u]=1;
	used[u]=1;
	for(i=1;i<n;++i)//  n-1  
	{
		double max=0;
		for(j=1;j<=n;++j)
		{
			if(!used[j]&&max<dis[j])
			{
				max=dis[j];
				pos=j;
			}
		} 		
		used[pos]=1;
		dis[pos]=max;
		for(j=1;j<=n;++j)// dis    ,    
		{
			if(!used[j]&&dis[j]<map[pos][j]*dis[pos])
			{
				dis[j]=map[pos][j]*dis[pos];
			}
		}
	}
}
int main()
{
	int m;
	double w;
	int u,v;
	while(~scanf("%d",&n))
	{		
		for(i=1;i<=n;++i)
      		for(j=1;j<=n;++j)
        	{
        		scanf("%lf",&w);
        		map[i][j]=w;
        	}
        	
        scanf("%d",&m);
        while(m--)
        {
        	scanf("%d%d",&u,&v);
           	dijkstra(u);
           	if(dis[v]==0) printf("What a pity!
"); else printf("%.3lf
",dis[v]); } } return 0; } /* 3 1 0.5 0.5 0.5 1 0.2 0.5 0.2 1 3 1 2 2 3 1 3 */