NYOJ 1274 河南省第九届ACM省赛 C题

信道安全

时间限制: 1000 ms  |  内存限制: 65535 KB
难度: 2
描述
Alpha 机构有自己的一套网络系统进行信息传送。情报员 A 位于节点 1,他准备将一份情报 发送给位于节点 n 的情报部门。可是由于最近国际纷争,战事不断,很多信道都有可能被遭到监 视或破坏。 经过测试分析,Alpha 情报系统获得了网络中每段信道安全可靠性的概率,情报员 A 决定选 择一条安全性最高,即概率最大的信道路径进行发送情报。 你能帮情报员 A 找到这条信道路径吗? 
输入
第一行: T 表示以下有 T 组测试数据 ( 1≤T ≤8 )
对每组测试数据:
第一行:n m 分别表示网络中的节点数和信道数 (1<=n<=10000,1<=m<=50000)
接下来有 m 行, 每行包含三个整数 i,j,p,表示节点 i 与节点 j 之间有一条信道,其信
道安全可靠性的概率为 p%。 ( 1<=i, j<=n 1<=p<=100)
输出
每组测试数据,输出占一行,一个实数 即情报传送到达节点 n 的最高概率,精确到小数点后
6 位。
样例输入
1
5 7
5 2 100
3 5 80
2 3 70
2 1 50
3 4 90
4 1 85
3 1 70
样例输出

61.200000


这个题考的最短路模板,我用的SPFA只用了58Ms,一开始用的迪杰斯特拉,10000*10000的数组直接mle,在下面会附上一段迪杰斯特拉AC的代码,用了边集数组优化,那个是学弟写的,个人认为SPFA确实好用,也推荐有SPFA处理最短路问题,这个题需要注意的是求最长路,而且数组的精度要处理好。

#include<stdio.h>
#include<queue>
#include<string.h>
#define inf 0x3f3f3f3f  
#define maxn 50005 
using namespace std;  
int n,m,len;  
struct node  
{  
    int next,v,u;
	double w;  
}ans[maxn*2];  
int first[maxn];
double dis[maxn];
int vis[maxn];  
void add(int u,int v,int w)  //数组模拟链表,next数组存储位置 
{  
	ans[len].u=u;
	ans[len].v=v;
	ans[len].w=w/100.0;  
    ans[len].next=first[u];  
    first[u]=len++;  
}  
void spfa(int st)  
{  
    dis[st]=1.0;  
    vis[st]=1;  
    queue<int>q;  
    q.push(st);  
    while(!q.empty())  
    {  
        st=q.front();  
        q.pop();  
        vis[st]=0;  
        for(int i=first[st];i!=-1;i=ans[i].next)  
        {  
            if(dis[ans[i].v]<dis[st]*ans[i].w)  
            {  
                dis[ans[i].v]=dis[st]*ans[i].w;  
                if(!vis[ans[i].v])  
                {  
                    vis[ans[i].v]=1;  
                    q.push(ans[i].v);  
                }  
            }  
        }  
    } 
	printf("%lf\n",dis[n]*100);   
}  
int main()  
{  
	//freopen("C:\\input.txt","r",stdin);
	int t;
	scanf("%d",&t);
	while(t--)
	{
		memset(dis,0,sizeof(dis));
		memset(vis,0,sizeof(vis));
		memset(first,-1,sizeof(first));
    	int x,y,z;  
    	scanf("%d%d",&n,&m);
    	int len=1;
        for(int i=1;i<=m;i++)  
        {  
           	scanf("%d%d%d",&x,&y,&z);  
            add(x,y,z);  
            add(y,x,z);   
       	}  
        spfa(1);  	
	}  
    return 0;  
}  

接下来给迪杰斯特拉的AC代码,用时911ms,刚好卡1s的界限

#include <bits/stdc++.h>
using namespace std;

const int MAXN = 10010;

double short_path(list<pair<int, double> > *ls, int n)
{
	double cos[MAXN]; //最高概率
	int vis[MAXN]; //访问
	memset(cos, 0, sizeof(cos));
	memset(vis, 0, sizeof(vis));
	for (list<pair<int, double> >::iterator it = ls[1].begin(); it != ls[1].end(); it++)
		cos[it->first] = it->second;
	vis[1] = 1;
	for (int i = 2; i < n; i++)
	{
		double _max = -1;
		int k;
		for (int j = 1; j < n; j++)
			if (!vis[j] && _max < cos[j])
			{
				_max = cos[j];
				k = j;
			}
			vis[k] = 1;
			for (list<pair<int, double> >::iterator it = ls[k].begin(); it != ls[k].end(); it++)
				if (!vis[it->first] && _max * it->second > cos[it->first])
					cos[it->first] = _max * it->second;
	}
	return cos[n];
}
int main()
{
#ifdef LOCAL
	freopen("C:/input.txt", "r", stdin);
#endif

	int t;
	cin >> t;
	for (int ti = 0; ti < t; ti++)
	{
		list<pair<int, double> > ls[MAXN];
		int n, m;
		cin >> n >> m;
		for (int mi = 0; mi < m; mi++)
		{
			int i, j, p;
			cin >> i >> j >> p;
			ls[i].push_back(pair<int, double>(j, p / 100.0));
			ls[j].push_back(pair<int, double>(i, p / 100.0));
		}
		printf("%.6lf\n", short_path(ls, n) * 100.0);
	}
	return 0;
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值