lightoj 1208

给组数,给边数给一个点,

给一堆边。

求包围的最小周长。

思路清晰,每条边只加一次,为逆时针缠绕。

然后化边为点,边到边如果左旋就有一个初始距离,然后求floyed。

lightoj 的>>不能连着写,不然就会挂。

#include <cstdio>
#include <iostream>
#include <cstdlib>
#include <algorithm>
#include <cstring>
#include <stack>
#include <cmath>
#include <map>
#include <vector>

using namespace std;
typedef pair<int,int> Point;

struct Edge
{
    Point rro,to;
    double dis;
};
map< Point , vector <int> > PE;
Edge e[110];

int isLeft(Point a,Point b,Point c)
{
    return (c.first-a.first)*(b.second-a.second)-(c.second-a.second)*(b.first-a.first)<=0;
}
double Dis(Point a,Point b)
{
    return sqrt((b.first-a.first)*(b.first-a.first)+(b.second-a.second)*(b.second-a.second));
}
double dp[110][110];
int main()
{
    int T,n,ncas=1;
    scanf ("%d",&T);
    while (T--)
    {
        PE.clear();
        Point BULL;
        scanf ("%d%d%d",&n,&BULL.first,&BULL.second);
        for (int i=0;i<n;i++)
        {
            scanf ("%d%d%d%d",&e[i].rro.first,&e[i].rro.second,&e[i].to.first,&e[i].to.second);
            if (!isLeft(e[i].rro,e[i].to,BULL))swap(e[i].rro,e[i].to);
            e[i].dis=Dis(e[i].rro,e[i].to);
//            printf ("(%f,%f),(%f,%f)\n",e[i].rro.x,e[i].rro.y,e[i].to.x,e[i].to.y);
//            printf ("%f\n",e[i].dis);
            PE[e[i].rro].push_back(i);
        }
        for (int i=0;i<110;i++)
        {
            for (int j=0;j<110;j++)
            {
                dp[i][j]=0x7f7f7f7f;
            }
        }
        for (int u=0;u<n;u++)
        {
            for (int v=0;v<PE[e[u].to].size();v++)
            {
                int bian=PE[e[u].to][v];
                if (isLeft(e[u].rro,e[u].to,e[bian].to))
                {
//                    printf ("YES\n");
                    dp[u][bian]=e[u].dis+e[bian].dis;
                }
            }
        }
        for (int k=0;k<n;k++)
        {
            for (int i=0;i<n;i++)
            {
                for (int j=0;j<n;j++)
                {
                    dp[i][j]=min(dp[i][k]+dp[k][j],dp[i][j]);
                }
            }
        }
        double ans=0x7f7f7f7f;
        for (int i=0;i<n;i++) ans=min(ans,dp[i][i]);
        if (fabs(ans-0x7f7f7f7f)<1e-9)
        {
            printf ("Case %d: -1.000\n",ncas++);
        }
        else
            printf ("Case %d: %.10f\n",ncas++,ans);
    }
    return 0;
}

 

posted on 2016-07-05 22:59  very_czy  阅读(203)  评论(0编辑  收藏  举报

导航