NYOJ1274信道安全

NYOJ1274

    知识点1

    这个题如果不想用指针,可以用数组的方法去实现邻接链表。

       先打个比方:

       0   1  2  3  4  5   数组下标

       -1  0  4 -1  3  -1  存的内容

       可以表示为:

        点 1存下标0  0与任何点都不连接,即链接结束      0 1是有关系的

        点 2存下标4 , 4 存下标3, 3存下标-1即链接结束   2 3 4是有关系的一条链

        点 5独立。

        我们可以把每一条链对应的一个点关联起来,就可以表示邻接链表了。

        再开一个数组 存储每一天链的开头,如 a【0】 = 2;联系本题,则表示 点0 与2 3 4一条链有关联,

      及2 3 4所在的位置不仅存着链接下一个链的 next 还有本 位置对应的一个点表示与0点可通路的点信息。

        点击细节->更详细的数组表示邻接表的思想(初学者必看)

       知识点2

        我个人认为本题不需要用数组记录走过的点,因为即使出现环路状况,因为本题特点  越乘越小的性质(与最短路 成环路越加越大),都是背离答案目标的,因此不需要设置。用队列间接地实现了动态规划,由于只

 有 新更新的点 进行更新 新的路径,减少循环次数了。

      

     

#include <stdio.h>  
#include <string.h>  
#include <queue>  
using namespace std;  
int first[50001];
queue<int> a;

double dis[10001];
struct node
{
	int b,e;
	double w;
	int next;
}edge[50001];

int num;
void add_edge(int b, int e ,double w)
{
	edge[num].b  = b;
	edge[num].e  = e;
	edge[num].w  = w;

	edge[num].next  = first[b];
	first[b] = num;
	num++;

}

void SPFA()
{
   int i,begin,b,e;
   memset(dis,0,sizeof(dis));
   
   a.push(1);
   begin = first[1];
   b = edge[begin].b;
   dis[b] = 1.0;
   
   while(!a.empty())
   {
   	    begin = a.front();
   	    a.pop() ;
   
        if(b == -1)continue;
        b = begin;
  
   	    for(i = first[begin] ; i != -1; i = edge[i].next)
   	    {
   	       e = edge[i].e;
   	   
   	       if(dis[e] < dis[b]*edge[i].w)	
   	       {
   	       	  dis[e] = dis[b]*edge[i].w;
              a.push(e);
     
		   }
	
		}
   	
   }

}
int main()
{
	int T,n,m,i,b,e;
	double w;
	scanf("%d",&T);


	while(T--)
	{
		scanf("%d %d",&n,&m);
	    num = 0;
	    memset(first,-1,sizeof(first));
	    memset(vis,0,sizeof(vis));
		for(i = 0;i<m;i++)
		{
			scanf("%d %d %lf",&b,&e,&w);//lf细节 
			
			add_edge(b,e,w/100);
			add_edge(e,b,w/100);
		}
      
		SPFA();

		printf("%.6f\n",dis[n]*100);

		
	}
	return 0;
}

   


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值