zoukankan      html  css  js  c++  java
  • ural 1143. Electric Path(凸包上最短哈密顿路径)

    题目链接:http://acm.timus.ru/problem.aspx?space=1&num=1143

    题意:逆时针给一个凸包的n(n<=200)个顶点坐标,求一个最短哈密顿路径的长度。


    解法:求最短哈密顿本身是一个NP问题,可是由于是凸包上,能够利用这个做;有一个性质:凸包上的最短哈密顿路径不会出现交叉。所以能够看出来从一点出发,他要么和顺时针相邻点连接,要么和逆时针相邻点相连接。通过这个性质能够通过dp做:

    ans[i][j][0]表示i開始。往后j的点最短路径长度,ans[i][j][0]表示i開始,往前j的点最短路径长度。


    转移方程见代码:有了转移方程枚举第一个起始位置即可,复杂度n^3.

    /******************************************************
    * @author:xiefubao
    *******************************************************/
    #pragma comment(linker, "/STACK:102400000,102400000")
    #include <iostream>
    #include <cstring>
    #include <cstdlib>
    #include <cstdio>
    #include <queue>
    #include <vector>
    #include <algorithm>
    #include <cmath>
    #include <map>
    #include <set>
    #include <stack>
    #include <string.h>
    //freopen ("in.txt" , "r" , stdin);
    using namespace std;
    
    #define eps 1e-8
    #define zero(_) (abs(_)<=eps)
    const double pi=acos(-1.0);
    typedef long long LL;
    const int Max=210;
    const int INF=1e9+7;
    
    struct point
    {
        double x,y;
        void read()
        {
            scanf("%lf%lf",&x,&y);
        }
    } points[Max];
    double dist[Max][Max];
    int t=0;
    int n;
    double getdis(int i,int j)
    {
        return dist[(i+t)%n][(j+t)%n];
    }
    double getdist(int i,int j)
    {
        i=(i+n)%n;
        j=(j+n)%n;
        return sqrt((points[i].x-points[j].x)*(points[i].x-points[j].x)+
                    (points[i].y-points[j].y)*(points[i].y-points[j].y));
    }
    double ans[Max][Max][2];
    double dfs(int i,int j,int st)
    {
        i=(i+n)%n;
        if(!zero(ans[i][j][st]))
            return ans[i][j][st];
        if(j==1)
            return ans[i][j][st]=getdis(i,i+(st?-1:1));
        if(!st)
            return ans[i][j][st]=min(dfs(i+1,j-1,0)+getdis(i,i+1),dfs(i+j,j-1,1)+getdis(i,i+j));
        else
            return ans[i][j][st]=min(dfs(i-1,j-1,1)+getdis(i,i-1),dfs(i-j,j-1,0)+getdis(i,i-j));
    }
    double solve()
    {
        memset(ans,0,sizeof ans);
        return min(dfs(1,n-2,0)+getdis(0,1),dfs(n-1,n-2,1)+getdis(0,n-1));
    }
    int main()
    {
        scanf("%d",&n);
        for(int i=0; i<n; i++)
            points[i].read();
        for(int i=0; i<n; i++)
            for(int j=i; j<n; j++)
            {
                dist[i][j]=getdist(i,j);
                dist[j][i]=dist[i][j];
            }
        double out=INF;
        out=min(out,solve());
        for(int i=0; i<n-1; i++)
        {
            t++;
            point p=points[0];
            for(int j=0; j<n-1; j++)
                points[j]=points[j+1];
            points[n-1]=p;
            out=min(out,solve());
        }
        printf("%.3f
    ",out);
        return 0;
    }
    


  • 相关阅读:
    Android Studio 单刷《第一行代码》系列 05 —— Fragment 基础
    Android Studio 单刷《第一行代码》系列 04 —— Activity 相关
    Android Studio 单刷《第一行代码》系列 03 —— Activity 基础
    Android Studio 单刷《第一行代码》系列 02 —— 日志工具 LogCat
    Android Studio 单刷《第一行代码》系列 01 —— 第一战 HelloWorld
    IDEA 内网手动添加oracle,mysql等数据源,以及server returns invalid timezone错误配置
    eclipse maven设置
    IntelliJ IDE 常用配置
    eclipse maven 常见问题解决方案
    Maven 安装和配置
  • 原文地址:https://www.cnblogs.com/llguanli/p/7047869.html
Copyright © 2011-2022 走看看