题意
哗啦啦村袭击了喵哈哈村!
度度熊为了拯救喵哈哈村,带着自己的伙伴去救援喵哈哈村去了!度度熊与伙伴们很快的就过来占据了喵哈哈村的各个军事要地,牢牢的守住了喵哈哈村。
但是度度熊发现,这是一场旷日持久的战斗,所以度度熊决定要以逸待劳,保存尽量多的体力,去迎战哗啦啦村的战士。
于是度度熊决定派尽量多的人去休息,但是同时也不能松懈对喵哈哈村的保护。
换句话而言,度度熊希望尽量多的人休息,而且存在一个包围圈由剩下的人组成,且能够恰好的包围住喵哈哈村的所有住房(包括边界)。
请问最多能让多少个人休息呢?
题解
当时看这个题的时候,完全不会做-w-
于是今天重新看了一次
发现我会做啦!!这好像没什么好骄傲啊吧
我们认为地规定一个方向,就是让点都在有向线段的左边
然后找最小环就可以了
CODE:
#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
using namespace std;
const int MAX=1<<28;
const int N=505;
int n,m;
int f[N][N];
struct qq
{
int x,y;
}a[N],b[N];
int mul (qq x,qq y,qq z)
{
int x1=x.x-z.x,y1=x.y-z.y;
int x2=y.x-z.x,y2=y.y-z.y;
return x1*y2-x2*y1;
}
int main()
{
while (scanf("%d",&n)!=EOF)
{
for (int u=1;u<=n;u++) scanf("%d%d",&a[u].x,&a[u].y);
scanf("%d",&m);
for (int u=1;u<=m;u++) scanf("%d%d",&b[u].x,&b[u].y);
for (int u=1;u<=m;u++)
for (int i=1;i<=m;i++)
{
if (u==i)
{
f[u][i]=MAX;
continue;
}
int cnt=0,cnt1=0;
for (int j=1;j<=n;j++)
{
if (mul(a[j],b[u],b[i])>0) cnt++;
if (mul(a[j],b[u],b[i])<0) cnt1++;
if (cnt!=0) break;
}
if (cnt==0) f[u][i]=1;
else f[u][i]=MAX;
}
/*for (int u=1;u<=m;u++)
{
for (int i=1;i<=m;i++)
printf("%d ",f[u][i]);
printf("\n");
}*/
for (int u=1;u<=m;u++)
for (int i=1;i<=m;i++)
{
if (f[i][u]==MAX) continue;
for (int j=1;j<=m;j++)
f[i][j]=min(f[i][j],f[i][u]+f[u][j]);
}
/*for (int u=1;u<=m;u++)
{
for (int i=1;i<=m;i++)
printf("%d ",f[u][i]);
printf("\n");
}*/
int ans=MAX;
for (int u=1;u<=m;u++)
ans=min(ans,f[u][u]);
if (ans==MAX) printf("ToT\n");
else printf("%d\n",m-ans);
}
return 0;
}