Information Transmission-3

题目描述:

There is n bases in a certain area, numbered 1, 2,. … … , n, the location of base i is represented by coordinates (xi, yi). Dr. Kong is at point (x1, y1), he must send an information to point (xn, yn). Because of the insecurity of the network, he decided to drive the information in person. When he is ready to leave, he find that there is something wrong with the steering wheel of his car. The steering wheel can only turn right and can not turn left. All roads in the area are known . If there is a road from base i to base j, the path length of the road is calculated from the coordinates sqrt((xi-xj)2 +(yi-yj)2) , assuming that all roads are two-way. At first, Dr. Kong may choose any road to set off from base 1. Once he leaves, he can only go straight or turn right at a given coordinate point. For faster transmission of information , Can you help Dr. Kong design a shortest path from Base 1 to Base n without turning left on the steering wheel?

输入描述:

The first line of the input contains one integer T, which is the number of test cases (1<=T<=5). Each test case specifity:

  • Line 1: n m n bases, m roads1≤n≤100,1≤m≤200)
  • Line 2~n+1: xi yi the location of base i ( 2 integers,0≤xi,yi≤1000)
  • Line n+2~n+m+1: ik jk there is a road from base ik to base jk

输出描述:

For each test case generate a single line: a real number, the shortest path from Base 1 to Base n without turning left on the steering wheel. accurate to 2 decimal places.

样例输入:

1
5 6
10 10
10 5
30 5
12 30
15 0
1 2
2 5
3 5
1 3
1 4
4 5

样例输出:

36.43

来源:

河南省第十二届大学生程序设计竞赛

题目解析:

怎么说呢,是一道不算是很复杂的最短路径问题,最为烦躁的地方就在于,每次都要求向右拐,所以要判断是否吻合条件

设p1=(x1,y1), p2=(x2,y2), p3=(x3,y3)

求向量

p12=(x2-x1,y2-y1)

p23=(x3-x2,y3-y2)

则当 p12与 p23 的叉乘(向量积)

p12 x p23 = (x2-x1)(y3-y2)-(y2-y1)(x3-x2)

为正时,p1-p2-p3 路径的走向为逆时针,

为负时,p1-p2-p3 走向为顺时针

为零时,p1-p2-p3 所走的方向不变,亦即三点在一直线上

代码具体实现:

#include<bits/stdc++.h>
using namespace std;
int x[205];
int y[205];
double a[205][205];
double lu[205];
int shangx[205];
int shangy[205];
int visit[205];
int n,m;
double juli(int x1,int x2,int y1,int y2)
{
    return sqrt((x1-x2)*(x1-x2)+(y1-y2)*(y1-y2));
}
int dijkstra()
{
    int i;
    for(i=1;i<=n;i++)
    {
        lu[i]=a[i][1];
        shangx[i]=x[1];
        shangy[i]=y[1];
    }
    visit[1]=1;
    lu[1]=0.0;
    for(int j=1;j<n;j++)
    {
        int t;
        double minn=99999.9;
        for(i=1;i<=n;i++)
        {
            if(visit[i]==0&&lu[i]<minn)
            {
                minn=lu[i];
                t=i;
            }
        }
        visit[t]=1;
        for(i=1;i<=n;i++)
        {
            if(visit[i]==0)
            {
                if(lu[i]>lu[t]+a[t][i]&&((x[t]-shangx[t])*(y[i]-y[t])-(y[t]-shangy[t])*(x[i]-x[t]))<=0)
                {
                    lu[i]=lu[t]+a[t][i];
                    shangx[i]=x[t];
                    shangy[i]=y[t];
                }
            }
        }
    }
    printf("%.2lf\n",lu[n]);
}
int main()
{
    int t;
    scanf("%d",&t);
    while(t--)
    {
        memset(x,0,sizeof(x));
        memset(y,0,sizeof(y));
        memset(visit,0,sizeof(visit));
        memset(shangx,0,sizeof(shangx));
        memset(shangy,0,sizeof(shangy));
        for(int i=0;i<=205;i++)
        {
            for(int j=0;j<=205;j++)
            {
                a[i][j]=999999.0;
            }
        }
        scanf("%d%d",&n,&m);
        int i;
        for(i=1;i<=n;i++)
        {
            scanf("%d%d",&x[i],&y[i]);
        }
        for(i=0;i<m;i++)
        {
            int xx,yy;
            scanf("%d%d",&xx,&yy);
            a[xx][yy]=a[yy][xx]=juli(x[xx],x[yy],y[xx],y[yy]);
        }
        dijkstra();
    }
    return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值