hdu1596——find the safest road【最短路 】

find the safest road

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


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.400

0.500

题目链接:点击打开链接

这道题很容易知道考察的是最短路,但是又和最短路稍有不同,因为安全系数越高越好,因此要在最短路算法的基础上稍加

修改,这道题我打算用dij,spfa,spfa领接表优化写法,floyd都解答一遍

#include<cstdio>
#include<algorithm>
#include<cstring>
#include<iostream>
#define mod 10000007
using namespace std;
double e[1001][1001];
int s[1001][1001];
int main(){
	int n;
	//double inf=99999999.0;
	while(~scanf("%d",&n)){
		int i,j,k;
		for(i=1;i<=n;i++){
			for(j=1;j<=n;j++){
				scanf("%lf",&e[i][j]);
				s[i][j]=0;
			}
		}
		for(k=1;k<=n;k++){
			for(i=1;i<=n;i++){
				for(j=1;j<=n;j++){
					if(e[i][j]<=e[i][k]*e[k][j]&&e[i][k]>0&&e[k][j]>0){
						e[i][j]=e[i][k]*e[k][j];//不断更新安全系数的最大值
						s[i][j]=1;//两条路之间可以联通
					}
				}
			}
		}
		int t;
		scanf("%d",&t);
		while(t--){
			int a,b;
			scanf("%d %d",&a,&b);
			if(s[a][b]){
				printf("%.3lf\n",e[a][b]);
			}
			else{
				printf("What a pity!\n");
			}
		}
	}
	return 0;
}
StatusAccepted
Time3775ms
Memory11296kB
Length721
LangG++
dij写法,及其用时
#include<cstdio>
#include<iostream>
#include<algorithm>
#include<cstring>
#define INF 0x3f3f3f
using namespace std;
double dis[1005],cost[1005][1005];
int vis[1005]; 
int n;
void dij(int s){
	int u,v,i,j;
	memset(vis,0,sizeof(vis));
	for(i=1;i<=n;i++){
		dis[i]=cost[s][i];//代表出发点到各个顶点的初始路程 
	}
	vis[s]=1;
	dis[s]=1.0;//自身的安全系数为1 
	for(i=1;i<=n;i++){
		double min=-INF;
		for(j=1;j<=n;j++){
			if(vis[j]==0&&dis[j]>min){
				min=dis[j];
				u=j;
			}
		}
		vis[u]=1;
		for(v=1;v<=n;v++){
			if(!vis[v]){
				dis[v]=max(dis[v],dis[u]*cost[u][v]);
			}
		}
	}
}
int main(){
	while(~scanf("%d",&n)){
		//memset(cost,0,sizeof(cost));
		for(int i=1;i<=n;i++){
			for(int j=1;j<=n;j++){
				scanf("%lf",&cost[i][j]);
			}
		}
		int q,a,b;
		scanf("%d",&q);
		while(q--){
			scanf("%d%d",&a,&b);
			dij(a);
			if(dis[b]==0.0) printf("What a pity!\n");
			else printf("%.3lf\n",dis[b]);
		}
	}
	return 0;
}
StatusAccepted
Time1513ms
Memory8296kB
Length898
LangC++
spfa写法及其用时:
StatusAccepted
Time1482ms
Memory8360kB
Length892
LangC++
#include<iostream>
#include<cstdio>
#include<algorithm>
#include<queue>
#include<cstring>
#define INF 0x3f3f3f3f
using namespace std;
double dis[1005],cost[1005][1005];
int vis[1005];
int n;
void spfa(int s){
	memset(vis,0,sizeof(vis));
	for(int i=1;i<=n;i++){
		dis[i]=0;
	}
	queue<int> que;
	dis[s]=1;
	vis[s]=1;
	que.push(s);
	while(!que.empty()){
		int x=que.front();
		que.pop();
		vis[x]=0;
		//扫描所有出边
		for(int i=1;i<=n;i++){
			if(cost[x][i]&&dis[i]<dis[x]*cost[x][i]){
			dis[i]=max(dis[i],dis[x]*cost[x][i]);
			if(!vis[i]){
				que.push(i);
				vis[i]=1;
			}
			}
		} 
	}
}
int main(){
	while(~scanf("%d",&n)){
		memset(cost,0,sizeof(cost));
		for(int i=1;i<=n;i++){
			for(int j=1;j<=n;j++){
				scanf("%lf",&cost[i][j]);
			}
		}
		int q,a,b;
		scanf("%d",&q);
		while(q--){
			scanf("%d%d",&a,&b);
			spfa(a);
			if(dis[b]==0.0) printf("What a pity!\n");
			else printf("%.3lf\n",dis[b]);
		}
	}
	return 0;
}

spfa领接表优化写法:


Safest Points

04-16

Himekaidou Hatate (姫海棠はたて) is a crow tengu with the ability of spirit photography. The newspaper she writes, Kakashi Spirit News (「花果子念報」) is much less popular than Shameimaru Aya's Bunbunmaru News (「文々。新聞」). In order to beat Aya, Hatate decides to report Toramaru Shou, the disciple of Bishamonten (多闻天王). But it's not easy to take pictures of Shou and her bullet patterns while avoiding them as well.nnnAssum that both Hatate and Shou stay in a w*h grid region. Shou fire lasers out in straight lines, the i-th laser starts at (xi, yi) and moves in direction (dxi, dyi). The Manhattan distance of any two points (x1, y1) and (x2, y2) is |x1 - x2| + |y1 - y2|. Any point with a Manhattan distance to some laser that is less that 1 is called dangerous point. All other points are safe points. The points which have maximum Manhattan distance to dangerous points is called safest points. Hatate hopes that a new feature can be added to her camera - for each senario, finding out the safest points quickly. You're asked to develop this feature.nnInputnnThere are multiple cases. Each one describes a senario. The first line is "w h n", where 3 ≤ w, h ≤ 1000 and 1 ≤ n ≤ 1000 is the number of lasers. The i+1-th line is the i-th laser "xi yi dxi dyi", where 0 ≤ xi < w, 0 ≤ yi < h, dxi2 + dyi2 > 0. Process to the each of file.nnOutputnnFor each case, output all safest points seperated by a single blank in lexicographic order. If there are no safe points, output "MISS!" instead.nnSample Inputnn3 3 3n0 0 2 1n0 1 2 1n0 2 2 -2n4 4 2n0 0 3 3n3 0 -1 1n5 5 2n4 4 -1 -1n0 4 2 -2nSample OutputnnMISS!n(0, 1) (0, 2) (1, 0) (1, 3) (2, 0) (2, 3) (3, 1) (3, 2)n(0, 2) (2, 0) (2, 4) (4, 2) 问答

没有更多推荐了,返回首页