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;
}
时间: 2024-10-11 22:24:43

lightoj 1208的相关文章

LightOJ 1030 Discovering Gold【概率】

题目链接:http://www.lightoj.com/volume_showproblem.php?problem=1030 题意:基础概率题. 代码: #include <stdio.h> #include <string.h> #include <vector> #include <string> #include <algorithm> #include <iostream> #include <iterator>

LightOJ - 1370 Bi-shoe and Phi-shoe

题目链接:http://lightoj.com/login_main.php?url=volume_showproblem.php?problem=1370 题目大意:给N个数a[i], N <= 1e6,问使 Φ(x) >= a[i] 成立的最小x的所有x的和是多少. 解题思路:我们知道的是对于素数 m 来说,phi[m] = m - 1.另一方面,对于一个合数 m 来说, phi[m] < phi[x] , x > m && x 是素数. 因此,我们可以认为,每

lightoj 1057 - Collecting Gold(状压dp)

题目链接:http://www.lightoj.com/volume_showproblem.php?problem=1057 题解:看似有点下记忆话搜索但是由于他是能走8个方向的也就是说两点的距离其实就是最大的x轴或y轴的差.然后只有15个藏金点状压一下加dfs就行了. #include <iostream> #include <cstring> #include <cstdio> #include <cmath> #define inf 0X3f3f3f

hzau 1208 Color Circle(dfs)

1208: Color Circle Time Limit: 1 Sec  Memory Limit: 1280 MBSubmit: 289  Solved: 85[Submit][Status][Web Board] Description There are colorful flowers in the parterre in front of the door of college and form many beautiful patterns. Now, you want to fi

Lightoj 1088 - Points in Segments 【二分】

题目链接:http://www.lightoj.com/volume_showproblem.php?problem=1088 题意: 有一维的n个点和q条线段.询问每条线段上的点有多少个: 思路:寻找这些点中对于每条线段的上下界即可. 代码: #include <stdio.h> #include <ctime> #include <math.h> #include <limits.h> #include <complex> #include

Lightoj 1090 - Trailing Zeroes (II)

题目连接: http://www.lightoj.com/volume_showproblem.php?problem=1090 题目大意: 给出n,r,p,q四个数字1<=n,r,p,q<=1000000,求出的末尾有几个0? 解题思路: 是不是一下子懵了,数字好大,复杂度好高,精度怎么办···············,就问你怕不怕? 因为你是Acmer,这都不应该是问题.因为10的因子只有2和5,所以可以打表保存从1到当前数字相乘的积中分别含有2,5的个数.然后算出中分别含有2,5的个数,

暑期训练狂刷系列——Lightoj 1084 - Winter bfs

题目连接: http://www.lightoj.com/volume_showproblem.php?problem=1084 题目大意: 有n个点在一条以零为起点的坐标轴上,每个点最多可以移动k,问最终能不能把所有点都聚集在大于等于三个点的集合里面,如果能最少需要几个这样的集合? 解题思路: 刚开始看到题目感觉好简单,就开始了sort然后贪心之旅,这就是错误的开始.最后发现这样并不行,然后再Alex的提醒下想用单调队列优化,在我愚昧的理解下竟然写成了bfs,提交竟然ac了,surprise~

LightOJ - 1148 - Mad Counting

先上题目: 1148 - Mad Counting   PDF (English) Statistics Forum Time Limit: 0.5 second(s) Memory Limit: 32 MB Mob was hijacked by the mayor of the Town "TruthTown". Mayor wants Mob to count the total population of the town. Now the naive approach to

LightOJ 1013 LCS+记忆化搜索

http://www.lightoj.com/volume_showproblem.php?problem=1013 题目大意: 给两个字符串,问最短的满足子串包含给的两个字符串的字符串的最短长度,以及最短长度的字符串的个数. 第一个问题就是简单的LCS,两个串长度和减去公共部分. 第二个问题要进行记忆话搜索来查找.dp(i,j,l)(第一个串i位,第二个串j位,总串l位) 转移方程 dp(i,j,l) = dp(i-1,j-1,l-1) (s1[i] = s2[j]时) dp(i,j,l) =