您的位置:首页 > 其它

lightoj 1208

2016-07-05 22:59 337 查看
给组数,给边数给一个点,

给一堆边。

求包围的最小周长。

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

然后化边为点,边到边如果左旋就有一个初始距离,然后求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;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: