hdu 6080 度度熊保护村庄(floydS使用技巧)

度度熊保护村庄

Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)
Total Submission(s): 124    Accepted Submission(s): 53


Problem Description
哗啦啦村袭击了喵哈哈村!

度度熊为了拯救喵哈哈村,带着自己的伙伴去救援喵哈哈村去了!度度熊与伙伴们很快的就过来占据了喵哈哈村的各个军事要地,牢牢的守住了喵哈哈村。

但是度度熊发现,这是一场旷日持久的战斗,所以度度熊决定要以逸待劳,保存尽量多的体力,去迎战哗啦啦村的战士。

于是度度熊决定派尽量多的人去休息,但是同时也不能松懈对喵哈哈村的保护。

换句话而言,度度熊希望尽量多的人休息,而且存在一个包围圈由剩下的人组成,且能够恰好的包围住喵哈哈村的所有住房(包括边界)。

请问最多能让多少个人休息呢?
 

Input
本题包含若干组测试数据。

第一行一个整数n,表示喵哈哈村的住房数量。

接下来n行,每行两个整数(x1[i],y1[i]),表示喵哈哈村的住房坐标。

第n+1行一个整数m,表示度度熊的士兵数量。

接下来m行,每行两个整数(x2[i],y2[i]),表示度度熊伙伴的坐标。

满足:

1<=n,m<=500

-10000<=x1[i],x2[i],y1[i],y2[i]<=10000
 

Output
请输出最多的人员休息的数目。

如果无法保护整个村庄的话,输出"ToT"
 

Sample Input
  
  
2 1 1 2 2 4 0 0 0 4 4 2 4 0 1 1 1 2 0 0 0 1
 

Sample Output
  
  
1 ToT

判断整个村庄是否在两个点的左侧,如果在就连边,最后判断一个点到自身的最短距离(即环的大小)即可;

#include <iostream>
#include <cstdio>
#include <cstring>
#include <cmath>
#include <algorithm>
#include <map>
#include <queue>
#include <bitset>
using namespace std;
typedef long long LL;
const int N = 507;
struct node
{
    int x, y;
    node operator -(const node &A)const
    {
        node c;
        c.x=x-A.x,c.y=y-A.y;
        return c;
    }
    double operator *(const node &A)const
    {
        return x*A.y-y*A.x;
    }
}a[N], b[N];
int w[N][N];
int judge(node A,node B,node C)
{
    int xmaxt=max(A.x,B.x),xmint=min(A.x,B.x);
    int ymaxt=max(A.y,B.y),ymint=min(A.y,B.y);
    if(C.x>=xmint&&C.x<=xmaxt&&C.y>=ymint&&C.y<=ymaxt) return 0;
    return 1;
}

int main()
{
    int n, m;
    while(scanf("%d", &n)!=EOF)
    {
        memset(w,0x3f3f3f3f,sizeof(w));
        for(int i=0;i<n;i++) scanf("%d %d", &b[i].x, &b[i].y);
        scanf("%d", &m);
        for(int i=0;i<m;i++) scanf("%d %d", &a[i].x, &a[i].y);
        for(int i=0;i<m;i++)
        {
            for(int j=0;j<m;j++)
            {
                int flag=0;
                 for(int k=0;k<n;k++)
                 {
                     //cout<<(a[j]-a[i])*(b[k]-a[i])<<endl;
                     if((a[j]-a[i])*(b[k]-a[i])<0||((a[j]-a[i])*(b[k]-a[i])==0&&judge(a[i],a[j],b[k])))
                     {
                         flag=1;
                         break;
                     }
                 }
                 if(!flag) w[i][j]=1;
            }
        }
        for(int k=0;k<m;k++)
        {
            for(int i=0;i<m;i++)
            {
                if(w[i][k]==0x3f3f3f3f) continue;
                for(int j=0;j<m;j++)
                {
                    w[i][j]=min(w[i][k]+w[k][j],w[i][j]);
                }
            }
        }
        int ans=0x3f3f3f3f;
        for(int i=0;i<m;i++) ans=min(ans,w[i][i]);
        if(ans>m) puts("ToT");
        else cout<<m-ans<<endl;
    }
    return 0;
}







评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值