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;
    }
    


  • 相关阅读:
    window下安装jupyter,ipython的方法
    虚拟机中,安装VM tools的小发现
    Perl 与 Python 之间的一些异同
    perl中的grep函数介绍
    基因芯片(Affymetrix)分析1:芯片质量分析
    议员是如何投票的?
    社会网络分析:探索人人网好友推荐系统
    支持向量机(一)
    主成分分析(Principal components analysis)-最小平方误差解释
    因子分析(Factor Analysis)
  • 原文地址:https://www.cnblogs.com/llguanli/p/7047869.html
Copyright © 2011-2022 走看看