码迷,mamicode.com
首页 > 其他好文 > 详细

[P2526][SHOI2001]小狗散步

时间:2018-07-22 00:35:13      阅读:175      评论:0      收藏:0      [点我收藏+]

标签:接下来   fir   clu   http   second   sizeof   pac   int   ++   

Link:

P2526 传送门

Solution:

一道提示非常到位的题目

题面中强调了在两个路径相邻点间只能再去至多一个点,且每个点只计算一次贡献

于是明显可以将原题看作询问在两个不相交点集间最多能连几条边

接下来将合法边连上跑二分图匹配就好了

 

Tip:二分图匹配时分清$X,Y$集合以及$match$数组是哪个集合的匹配值

Code:

#include <bits/stdc++.h>

using namespace std;
typedef pair<int,int> P;
#define X first
#define Y second
const int MAXN=105;
P a[MAXN],b[MAXN];
vector<int> G[MAXN];
int n,m,mat[MAXN],vis[MAXN],idx=1;

int dfs(int x)
{
    vis[x]=idx;
    for(int i=0;i<G[x].size();i++)
    {
        int v=G[x][i],m=mat[v];
        if(m==-1||vis[m]!=idx&&dfs(m))
        {mat[v]=x;return 1;}
    }
    return 0;
}

double dist(P a,P b)
{return sqrt((a.X-b.X)*(a.X-b.X)+(a.Y-b.Y)*(a.Y-b.Y));}

int main()
{
    memset(mat,-1,sizeof(mat));
    scanf("%d%d",&n,&m);
    for(int i=1;i<=n;i++)
        scanf("%d%d",&a[i].X,&a[i].Y);
    for(int i=1;i<=m;i++)
        scanf("%d%d",&b[i].X,&b[i].Y);
    for(int i=2;i<=n;i++)
    {
        double d=dist(a[i],a[i-1]);
        for(int j=1;j<=m;j++)
            if(2*d>=dist(a[i],b[j])+dist(a[i-1],b[j])) 
                G[j].push_back(i);
    }    
    
    int res=0;
    for(int i=1;i<=m;i++,idx++) res+=dfs(i);
    printf("%d\n",res+n);    
    for(int i=1;i<=n;i++)
    {
        if(mat[i]!=-1) 
            printf("%d %d ",b[mat[i]].X,b[mat[i]].Y);
        printf("%d %d ",a[i].X,a[i].Y);
    }
    return 0;
}

 

[P2526][SHOI2001]小狗散步

标签:接下来   fir   clu   http   second   sizeof   pac   int   ++   

原文地址:https://www.cnblogs.com/newera/p/9348269.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!