find the safest road
Time Limit: 10000/5000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)Total Submission(s): 6952 Accepted Submission(s): 2465
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所在的城市和要去的城市
第一行: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
Author
ailyanlu
Source
Recommend
思路 :最短路裸题,直接dij邻接矩阵暴力就能过,用优先队列和邻接表速度一样的都是1.6秒过邻接矩阵代码还更短
#include<iostream>
#include <cstdio>
#include <cstring>
#include <cmath>
#include <queue>
#include <cstdlib>
#include <algorithm>
using namespace std;
double w[1100][1100];
double d[1200];
int vis[1200],n;
void dij(int st)
{
memset(vis,0,sizeof(vis));
int i,j,x;
for(i = 1; i<= n; i++)
{
d[i] = 0;
}
double y;
d[st] = 1;
for(i = 1; i<=n;i++)
{
y = 0;
for(j = 1;j<=n;j++)
{
if(vis[j] == 0&&d[j] > y)
{
y = d[j];
x = j;
}
}
vis[x] = 1;
for(j = 1; j<=n;j++)
{
d[j] = max(d[j],d[x]*w[x][j]);
}
}
}
int main()
{
while (scanf("%d",&n)!=EOF)
{
int i,j;
double c;
memset(w,0,sizeof(w));
for(i = 1; i<=n;i++)
{
for(j = 1;j <= n; j++)
{
scanf("%lf",&w[i][j]);
}
}
int z;
cin>>z;
int a,b;
while (z--)
{
cin>>a>>b;
dij(a);
if(d[b]>0)
{
printf("%.3lf\n",d[b]);
}
else
{
cout<<"What a pity!"<<endl;
}
}
}
return 0;
}
邻接表和优先队列写的:
#include<iostream>
#include <cstdio>
#include <cstring>
#include <cmath>
#include <queue>
#include <cstdlib>
#include <algorithm>
using namespace std;
struct Edge
{
int u,v,next;
double w;
Edge(int a = 0, int b = 0, double c = 0)
{
u = a; v =b; w =c;
}
}e[1100000];
double d[1200];
int vis[1200],cnt,head[1200],n;
void add(Edge q)
{
e[cnt].u = q.u;
e[cnt].v = q.v;
e[cnt].w = q.w;
e[cnt].next = head [q.u];
head[q.u] = cnt++;
}
struct node
{
int vis;
double val;
friend bool operator < (node a, node b)
{
return a.val < b.val;
}
node (int a, double b)
{
vis = a;
val = b;
}
};
void dij(int st)
{
memset(vis,0,sizeof(vis));
int i,j;
for(i = 1; i<= n; i++)
{
d[i] = 0;
}
d[st] = 1;
node s(st,1);
priority_queue <node> q;
q.push(s);
while (!q.empty())
{
node w = q.top();
q.pop();
if(vis[w.vis] == 1)
{
continue;
}
vis[w.vis] = 1;
for( i = head[w.vis];i!=-1; i = e[i].next)
{
int begin = w.vis;
int end = e[i].v;
if(d[end]< d[begin]*e[i].w)
{
d[end] = d[begin]*e[i].w;
q.push(node(end,d[end]));
}
}
}
}
int main()
{
while (scanf("%d",&n)!=EOF)
{
int i,j;
cnt = 0;
double c;
memset(head,-1,sizeof(head));
for(i = 1; i<=n;i++)
{
for(j = 1;j <= n; j++)
{
scanf("%lf",&c);
if(c>0)
{
add(Edge(i,j,c));
}
}
}
int z;
cin>>z;
int a,b;
while (z--)
{
cin>>a>>b;
dij(a);
if(d[b]>0)
{
printf("%.3lf\n",d[b]);
}
else
{
cout<<"What a pity!"<<endl;
}
}
}
return 0;
}