zoukankan      html  css  js  c++  java
  • 【RQNOJ86】智捅马蜂窝【最短路】

    题目大意:

    题目链接:http://www.rqnoj.cn/problem/86
    一个坐标系上有nn个点n1n-1条边,有两种移动方式:

    1. 经过一条边从一个点到达另一个点,耗时为这条边长度÷vdiv v
    2. 从一个点垂直跳下到达正下方的另一个点。耗时为((YjYi)×2÷g)sqrt{((Y_j-Y_i) imes 2div g)} (注意:gg1010

    求从点11到点nn的最小时间。


    思路:

    对于移动方式11,直接利用勾股求出两点之间的距离,然后建一条双向边。
    对于移动方式22,就枚举所有的点,判断他们是否满足Xi=XiX_i=X_iYi>YjY_i>Y_j,如果满足,那么就在iijj中连一条单向边
    然后跑个最短路就可以了。


    代码:

    #include <cstdio>
    #include <iostream>
    #include <cmath>
    #include <cstring>
    #include <queue>
    #define N 200
    using namespace std;
    
    int n,tot,head[N];
    double v,dis[N];
    bool vis[N];
    
    struct edge
    {
    	int next,to;
    	double dis;
    }e[N*2];
    
    struct node
    {
    	double x,y;
    }a[N];
    
    double ask_dis(double x1,double y1,double x2,double y2)  //勾股求距离
    {
    	return sqrt((x1-x2)*(x1-x2)+(y1-y2)*(y1-y2));
    }
    
    void add1(int from,int to)  //移动方式1
    {
    	e[++tot].to=to;
    	e[tot].dis=ask_dis(a[from].x,a[from].y,a[to].x,a[to].y)/v/1.0;
    	e[tot].next=head[from];
    	head[from]=tot;
    }
    
    void add2(int from,int to,double dis)  //移动方式2
    {
    	e[++tot].to=to;
    	e[tot].dis=dis;
    	e[tot].next=head[from];
    	head[from]=tot;
    }
    
    void spfa()
    {
    	for (int i=1;i<=n;i++)
    	{
    		dis[i]=1000000000.0;
    		vis[i]=0;
    	}
    	queue<int> q;
    	q.push(1);
    	dis[1]=0.0;
    	vis[1]=1;
    	while (q.size())
    	{
    		int u=q.front();
    		q.pop();
    		vis[u]=0;
    		for (int i=head[u];~i;i=e[i].next)
    		{
    			int v=e[i].to;
    			if (dis[v]>dis[u]+e[i].dis)
    			{
    				dis[v]=dis[u]+e[i].dis;
    				if (!vis[v])
    				{
    					vis[v]=1;
    					q.push(v);
    				}
    			}
    		}
    	}
    }
    
    int main()
    {
    	memset(head,-1,sizeof(head));
    	cin>>n>>v;
    	int x,y,fa;
    	for (int i=1;i<=n;i++)
    	{
    		scanf("%d%d%d",&x,&y,&fa);
    		a[i].x=(double)x;
    		a[i].y=(double)y;
    		add1(i,fa);
    		add1(fa,i);
    	}
    	for (int i=1;i<=n;i++)
    	 for (int j=1;j<=n;j++)
    	  if (i!=j)
    	   if (a[i].x==a[j].x&&a[i].y>a[j].y)
    	    add2(i,j,sqrt((a[i].y-a[j].y)*2.0/10.0));
    	spfa();
    	printf("%0.2lf",dis[n]);
    	return 0;
    }
    
  • 相关阅读:
    [HNOI 2003] 消防局的设立
    Codeforces 341
    CF 专栏
    TC SRM 570
    TC SRM 588
    TC SRM 589
    TC专栏
    BZOJ 第二十一页 除草
    BZOJ 第二十二页 除草
    BZOJ 第二十三页 除草
  • 原文地址:https://www.cnblogs.com/hello-tomorrow/p/11998480.html
Copyright © 2011-2022 走看看