HDUOJ_1596(find the safest road)(dijkstra)

来源:互联网 发布:js 图片预览插件 编辑:程序博客网 时间:2024/06/15 20:35

HDUOJ_1596(find the safest road)(dijkstra)


find the safest road

Time Limit: 10000/5000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)
Total Submission(s): 9272    Accepted Submission(s): 3279


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
31 0.5 0.50.5 1 0.40.5 0.4 131 22 31 3
Sample Output
0.5000.4000.500


提示:安全系数越大,越安全。输入的数据如:1     0.5     0.5,表示第一个城市到自己的安全系数为1,第一个0.5表示第一个城市和第二个城市之间直接连通的道路安全系数为0.5,第二个0.5表示第一个城市和第三个城市之间直接连通的道路的安全系数为0.5.后面的数据依此类推。若出现数据为0。如:1     0     0.5,则表示第一个城市和第二个城市之间没有直接相连的公路(可能会有间接连通的公路)。若没有直接连通的道路时,可能需要走多条道路(间接到达)到达目的地。当走多条道路时,此时的安全系数为各条道路的安全系数的乘积(因此道路越少安全系数越高)。


My  solution:

/*2015.8.18*/

#include<stdio.h>#include<string.h>#include<algorithm>using namespace std;int mark[1010],n;double map[1010][1010],d[1010];void dijkstra(int s){int i,v;d[s]=1;/*起点到起点的安全系数最高为1*/while(1){v=-1;for(i=1;i<=n;i++)if(!mark[i]&&(v==-1||d[v]<d[i]))/*注意:选择安全系数大的元素*/v=i;      /*注意区分:此题和以前经常做的题不一样,以前找的是最小的元素*/if(v==-1)break;mark[v]=1;for(i=1;i<=n;i++)d[i]=max(d[i],d[v]*map[v][i]);/*取较大的值,以前经常遇到的是取较小的数(min()函数)*/}                    /*  d[v]*map[v][i],此题是乘积,以前经常遇到的是加*/}int main(){int i,j,a,b,m;while(scanf("%d",&n)==1){for(i=1;i<=n;i++)for(j=1;j<=n;j++)scanf("%lf",&map[i][j]);/*安全系数为实数*/scanf("%d",&m);/*此题的map数组不用初始化,因为此题输入的数据包括了任意两个城市之间所有组合情况*/ while(m--){scanf("%d%d",&a,&b);    memset(d,0,sizeof(d));/*注意d为实型数组,不过用这两种方法初始化都能AC*/   //for(i=1;i<=n;i++) /*d数组需全部初始化为0而不是以前的无穷大,因为安全系数为0,*/  //d[i]=0;/**/    /*说明两个城市不连通,之前的题为了说明不连通,都初始化为无穷大*/     memset(mark,0,sizeof(mark));dijkstra(a);if(d[b]==0)/*安全系数为0说明不能到达目的地*/printf("What a pity!\n");elseprintf("%.3lf\n",d[b]);}}return 0; } 

对于整型数据,memset()函数,可以填充的值有三个,0和-1,0x3f(把数组全部初始化为无穷大)。这是因为计算机中用二进制补码表示数字,0的二进制补码为全0,-1的二进制补码为全1,0x3f3f3f3f(无穷大)的每个字节都是0x3f。如果要初始化为其它的值,可以用一个for循环。不过该题把实型数组初始化为0,也能AC说明,memset()函数也可以把实型数组初始化为0。以后要记住这个结论。

0 0
原创粉丝点击