有限制最短路hdu4179

F.A.Q
Hand In Hand
Online Acmers
Forum | Discuss
Statistical Charts
Problem Archive
Realtime Judge Status
Authors Ranklist
 
      C/C++/Java Exams     
ACM Steps
Go to Job
Contest LiveCast
ICPC@China
Best Coder beta
VIP | STD Contests
Virtual Contests 
    DIY | Web-DIY beta
Recent Contests

Difficult Routes

Time Limit: 5000/2000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)
Total Submission(s): 842    Accepted Submission(s): 149


Problem Description
In preparation for the coming Olympics, you have been asked to propose bicycle training routes for your country's team. The training committee wants to identify routes for traveling between pairs of locations in multiple sites around the country. Each route must have a desired level of difficulty based on the steepness of its hills.  
You will be given a road map with the elevation data superimposed upon it. Each intersection, where two or more roads meet, is identified by its x- , y- , and z-coordinates. Each road starts and ends at an intersection, is straight, and does not contain bridges over or tunnels under other roads. The difficulty level, d, of cycling a road is 0 if the road is level or travelled in the downhill direction. The difficulty of a non-level road when travelled in the uphill direction is 100*rise / run  . Here rise is the absolute value of change in elevation and run is the distance between its two intersection points in its horizontal projection to the 2D-plane at elevation zero. Note that the level of difficulty for cycling a descending road is zero.
A route, which is a sequence of roads such that a successor road continues from the same intersection where its predecessor road finishes, has a level of difficulty d if the maximum level of difficulty for cycling among all its roads equals d. The committee is also interested in the chosen route between two selected locations, if such a route with the desired difficulty level exists, being the one with the shortest possible distance to travel.
Reminder: The floor function   X  means X truncated to an integer.
The figure shows a road map with three intersections for the three sample inputs.

The edge labels of the darker shaded surface give the level of difficulty of going up hill. The lighter shaded surface is the horizontal projection to the 2D-plane at elevation zero.
 

Input
Input consists of many road maps. Each map description begins with two non-negative integers N and M, separated by a space on a line by themselves, that represent the number of intersections and the number of roads, respectively. N <= 10000, M <= 30000. A value of both N and M equal to zero denotes the end of input data.
Each of the next N lines contains three integers, separated by single spaces, which represent the x-, y- and z-coordinates of an intersection. The integers have values between 0 and 10000, inclusive. Intersections are numbered in order of their appearance starting with the value one. Each of the following M lines contains two integers that represent start and end intersections of a road.
Finally, three integers s, t and d that represents the desired starting intersection number s, the finishing intersection number t and the level of difficulty d for a training route are given on line by themselves. A valid training route must have at least one road with a difficulty level of d, and no road with a difficulty level greater than d. 0 <= d <= 10. If the training route is meant to form a closed circuit, then s and t are the same intersection numbers.
 

Output
For each road map and desired route, the output consists of a single line that contains:
1. number denoting the shortest length of a training route rounded to one decimal places, or
2. the single word “None” if no feasible route exists.
 

Sample Input
      
      
3 3 0 0 0 100 100 6 200 0 7 1 2 2 3 3 1 1 2 3 3 3 0 0 0 100 100 6 200 0 7 1 2 2 3 3 1 1 1 4 3 3 0 0 0 100 100 6 200 0 7 1 2 2 3 3 1 2 1 5 0 0
 

Sample Output
      
      
341.5 283.1 None
题意:求一条从s到t的最短路,要求所有便的d都小于要求的D,并且有一条要等于D

思路:建两个图,然后从s和t分别求一次最短路,然后枚举等于D的边,更新答案

#include<iostream>
#include<cstdio>
#include<string>
#include<cstring>
#include<vector>
#include<cmath>
#include<queue>
#include<stack>
#include<map>
#include<set>
#include<algorithm>
using namespace std;
const int maxn=31010;
const double INF=100000000000000000.0;
const double eps=1e-6;
int N,M,S,T,D,num1,num2;
vector<pair<int,int> > is_d;
struct Point
{
    int x,y,z;
}p[maxn];
struct A//已知变
{
    int s,e;
    int d;
}E[maxn];
int head1[maxn],head2[maxn];
double dis1[maxn],dis2[maxn];
bool vis[maxn];
struct node
{
    int v,next;
    double f;
}edge1[maxn*2],edge2[maxn*2];
void init()
{
    num1=num2=0;
    memset(head1,-1,sizeof(head1));
    memset(head2,-1,sizeof(head2));
    is_d.clear();
}
void add_edge(node *edge,int &num,int x,int y,double f,int *head)
{
    edge[num].v=y;
    edge[num].next=head[x];
    edge[num].f=f;
    head[x]=num++;
}
void SPFA(int s,double *dis,int *head,node *edge)
{
    for(int i=0;i<=N;i++)
    {
        dis[i]=INF;
        vis[i]=0;
    }
    queue<int> q;
    q.push(s);
    vis[s]=1;
    dis[s]=0;
    while(!q.empty())
    {
        int u=q.front();q.pop();
        vis[u]=0;
        for(int i=head[u];i!=-1;i=edge[i].next)
        {
            int v=edge[i].v;
            double w=edge[i].f;
            if(dis[v]>dis[u]+w)
            {
                dis[v]=dis[u]+w;
                if(!vis[v])
                {
                    q.push(v);
                    vis[v]=1;
                }
            }
        }
    }
}
double cal(int a,int b)
{
    int x=p[a].x-p[b].x;
    int y=p[a].y-p[b].y;
    int z=p[a].z-p[b].z;
    double len=x*x+y*y+z*z;
    len=sqrt(len);
    return len;
}
bool solve()
{
    double ans=INF;
    int n=is_d.size();
    for(int i=0;i<n;i++)
    {

        int x=is_d[i].first;
        int y=is_d[i].second;
        double len=cal(x,y);
        if(dis1[x]<INF&&dis2[y]<INF&&dis1[x]+dis2[y]+len<ans)
            ans=dis1[x]+dis2[y]+len;
    }
    if(fabs(ans-INF)<eps)return false;
    printf("%.3lf\n",ans);
    return true;
}
int cald(int a,int b)
{
    if(p[a].z>=p[b].z)return 0;
    double len=(p[a].x-p[b].x)*(p[a].x-p[b].x)+(p[a].y-p[b].y)*(p[a].y-p[b].y);
    len=sqrt(len);
    return int((p[b].z-p[a].z)*100.0/len);
}
int main()
{
    while(scanf("%d%d",&N,&M)!=EOF,N||M)
    {
        init();
        for(int i=1;i<=N;i++)scanf("%d%d%d",&p[i].x,&p[i].y,&p[i].z);
        for(int i=1;i<=M;i++)
        {
            scanf("%d%d",&E[i].s,&E[i].e);
        }
        scanf("%d%d%d",&S,&T,&D);
        for(int i=1;i<=M;i++)
        {
            int a=E[i].s,b=E[i].e;

            int d1=cald(a,b);
            int d2=cald(b,a);
            double tmp=cal(E[i].s,E[i].e);
            if(d1<=D)
            {
                add_edge(edge1,num1,E[i].s,E[i].e,tmp,head1);
                add_edge(edge2,num2,E[i].e,E[i].s,tmp,head2);
            }
            if(d2<=D)
            {
                add_edge(edge1,num1,E[i].e,E[i].s,tmp,head1);
                add_edge(edge2,num2,E[i].s,E[i].e,tmp,head2);
            }
            if(d1==D)is_d.push_back(make_pair(a,b));
            if(d2==D)is_d.push_back(make_pair(b,a));
        }
        if(is_d.size()<1){printf("None\n");continue;}
        SPFA(S,dis1,head1,edge1);
        SPFA(T,dis2,head2,edge2);
        if(!solve())printf("None\n");
    }
    return 0;
}




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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值