zoukankan      html  css  js  c++  java
  • find the safest road HDU杭电1596【Dijkstra || SPFA】

    http://acm.hdu.edu.cn/showproblem.php?pid=1596


    Problem Description
    XX星球有非常多城市,每一个城市之间有一条或多条飞行通道。可是并非全部的路都是非常安全的。每一条路有一个安全系数s,s是在 0 和 1 间的实数(包含0,1),一条从u 到 v 的通道P 的安全度为Safe(P) = s(e1)*s(e2)…*s(ek) e1,e2,ek是P 上的边 。如今8600 想出去旅游,面对这这么多的路。他想找一条最安全的路。

    可是8600 的数学不好。想请你帮忙 ^_^

     

    Input
    输入包含多个測试实例,每一个实例包含:
    第一行:n。n表示城市的个数n<=1000;
    接着是一个n*n的矩阵表示两个城市之间的安全系数,(0能够理解为那两个城市之间没有直接的通道)
    接着是Q个8600要旅游的路线,每行有两个数字。表示8600所在的城市和要去的城市
     

    Output
    假设86无法达到他的目的地,输出"What a pity!",
    其它的输出这两个城市之间的最安全道路的安全系数,保留三位小数。
     

    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
    */

  • 相关阅读:
    工具资源系列之给 windows 虚拟机装个 mac
    工具资源系列之 github 上各式各样的小徽章从何而来?
    php 学习笔记之日期时间操作一箩筐
    2018-12-03 VS Code英汉词典插件v0.0.7-尝试词性搭配
    2018-11-29 VS Code英汉词典插件v0.0.6-改为TS实现, 加测试
    2018-11-27 中文代码示例之Programming in Scala笔记第七八章
    2018-11-23 手工翻译Vue.js源码:尝试重命名标识符与文本
    2018-11-21 手工翻译Vue.js源码第一步:14个文件重命名
    2018-11-16 中文代码示例之Programming in Scala笔记第四五六章
    2018-11-13 中文代码示例之Programming in Scala学习笔记第二三章
  • 原文地址:https://www.cnblogs.com/clnchanpin/p/6945841.html
Copyright © 2011-2022 走看看