千里独行Thousands of miles to ride alone

关于三国时期有很多流行的故事。 其中最著名的就是千里独行。 关羽保护二嫂,从徐都出发,经过五门,斩六将,终于在古城与刘备、张飞两兄弟重逢。 现在,你的任务是为关羽找到跑得比兔子还快的兄弟们的新路线。 假设关羽知道从徐渡到古城的所有道路,以及每道门都能安全通过的概率。 请帮助关羽找到一条概率最大的有效路线。 请注意,每个门最多只能通过一次。
There are many popular stories about the Three Kingdoms period. The most famous of which is thousands of miles to ride alone. Guan Yu protected the two sister-in-law, starting from Xu du, passed five gates, chopped six generals, and reunited finally with the two brothers Liu Bei and Zhang Fei in an ancient city. Now, your task is to find a new route for Guan Yu to find his brothers who runs faster than the rabbit. It is assumed that Guan Yu knows all the roads from Xu Du to the ancient city and the probability that each gate will be passed safely. Please help Guan Yu find a valid route with maximum probability. Note that each gate can pass at most once.

Input:

The first row is an integer T (1 <= T <= 10), whici is the number of tests.

For each test, the first row is an integer N (3 <= N <= 1000). The following N rows is a matrix,indicate the roads between the N-2 gates from Xu du to the ancient city. If it is 1 at the ith row the jth column, then there is one road from i to j, if it is 0, then there are no road from i to j. The last row of each test has N-2 real number, P (0 <= P <= 1), which is the probabilities for Guan Yu to pass the gate.

Output

The maximum probability for Guan Yu to starting from Xu Du and arriving the ancient city, accurate to 4 decimal places. If the probability is less than 0.0001, then output “ Cannot reach! ”.
测试输入:
1
5
0 1 0 1 0
0 0 1 0 0
0 0 0 1 1
0 0 0 0 1
0 0 0 0 0
0.5 0.6 0.1
输出:
Case 1: 0.3000

#include<bits/stdc++.h>
using namespace std;
//最短路径算法--dijkstra算法 
int n;
int matrix[1001][1001];
double pro[1000],c[1001][1001];
double r,lastPro[1001],maxx[1001];	//lastPro记录到第k个门的最大概率,maxx通过比较找到第K个门的最大概率,传递给lastPro 
bool s[1001];		//用于记录初始到点i是否有路径 
		
int main()
{ 	
	int t;
	cin>>t;
	for(int i=1;i<=t;i++)
	{
		
		cin>>n;
		for(int j=1;j<=n;j++)
		{
			maxx[j]=0.0; lastPro[j]=0.0; pro[j]=0.0; s[j]=0;	//归0 
			for(int k=1;k<=n;k++)
			{
				c[j][k] =1.1;	matrix[j][k]=0;		//归0 
				cin>>matrix[j][k];
			}
		}
		for(int j=2;j<n;j++) 	cin>>pro[j];
		pro[1]=1.0;pro[n]=1.0;//每个门的概率 
		
		for(int j=1;j<n;j++)
		{	
			for(int k=j+1;k<=n;k++)
			{
				if(matrix[j][k]==1)
				{
					if(k<n)		c[j][k]=pro[k];	
					else 		c[j][k]=1;		//直接到最后一个门不再乘概率 
					if(j==1)	lastPro[k]=pro[k];		//记录原点能直接到达的门 
				}
			}
		}
		
		int u;
		s[1]=1;	lastPro[1]=1.0;		//将原点记录进去
		for(int j=1;j<=n;j++)
		{
			double temp=0.0;	//每次循环前归零temp 
			for(int k=1;k<=n;k++)
			{
				if(lastPro[k]>temp&&s[k]==0)
				{
					u=k;			
					temp=lastPro[k];
				}
			}
			s[u]=1;		//把距离原点概率最大的记录进去 
			
			for(int k=1;k<=n;k++)
			{
				if(s[k]==0&&c[u][k]<=1)
				{
					r=lastPro[u]*c[u][k];
					if(r>maxx[k])
					{
						maxx[k]=r;		//maxx通过比较找到第K个门的最大概率,传递给lastPro
						lastPro[k]=maxx[k];	//lastPro记录到第k个门的最大概率					
					}	
				}	
			}
		}
		cout<<"Case "<<i<<": ";
		if(lastPro[n]<0.0001) cout<<"Cannot reach!"<<endl;
		else  cout<<fixed<<setprecision(4)<<lastPro[n]<<endl;
	}
	return 0;
} 
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

一只野指针.

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值