题目大意:在二维坐标系中,存在由n个点构成的轨迹L,从第1个点依次到第n个点。又存在m个点。主人以1单位的速度沿着轨迹L前进,主人又带了一条狗,小狗的速度为2单位,主人和狗共同从第1个点出发。小狗在主人从第i个点走到第i+1个点的途中可以到达m个点中的任意某个点,但必须满足在主人到达第i+1个点之前到达该点,并最多只能访问1个点。问小狗所能达到的最多的点数,并输出小狗的行走路线。
思路:由于有第i个到第i+1个点最多只能访问1个属于m的点,所以该问题就转化为二分图的最大匹配问题。套模板即可。
另外说明下匈牙利算法的核心思路:假设存在四个节点n1,n2,m1,m2;E={(n1,m1), (n1,m2), (n2,m1), (n2,m2)};一开始匹配n1-m1成功;第二次匹配n2-m1,由于n1-m2也能匹配,则删去匹配n1-m1,增加匹配n1-m2, n2-m1,匹配成功,此时的增广路P=m2->n1->m1->n2。
#include <iostream>
#include <cstdio>
#include <cmath>
#include <cstring>
using namespace std;
struct Point
{
int x,y;
}node_set_n[105],node_set_m[105];
int m,n;
bool graph[105][105],have_visited[105];
int link[105],ans[105];
double cal_distance(struct Point p1,struct Point p2)
{
double dx=(double)p1.x-p2.x;
double dy=(double)p1.y-p2.y;
return sqrt(dx*dx+dy*dy);
}
int dfs(int node_n)
{
int node_m;
for (node_m=1;node_m<=m;node_m++)
if (graph[node_n][node_m] && have_visited[node_m]==false)
{
have_visited[node_m]=true;
if (link[node_m]==-1 || dfs(link[node_m]))
{
link[node_m]=node_n;
ans[node_n]=node_m;
return 1;
}
}
return 0;
}
int max_match()
{
int i,match_num=0;
memset(link,-1,sizeof(link));
memset(ans,-1,sizeof(ans));
for (i=1;i<=n;i++)
{
memset(have_visited,false,sizeof(have_visited));
if (dfs(i))
match_num++;
}
return match_num;
}
int main()
{
int i,j;
double len;
while (scanf("%d%d",&n,&m)==2)
{
memset(graph,false,sizeof(graph));
for (i=1;i<=n;i++)
scanf("%d%d",&node_set_n[i].x,&node_set_n[i].y);
for (i=1;i<=m;i++)
scanf("%d%d",&node_set_m[i].x,&node_set_m[i].y);
for (i=1;i<n;i++)
{
len=cal_distance(node_set_n[i],node_set_n[i+1]);
for (j=1;j<=m;j++)
if (cal_distance(node_set_n[i],node_set_m[j])+cal_distance(node_set_n[i+1],node_set_m[j])<=2*len)
graph[i][j]=true;
}
printf("%d\n",n+max_match());
for (i=1;i<n;i++)
{
printf("%d %d ",node_set_n[i].x,node_set_n[i].y);
if (ans[i]!=-1)
printf("%d %d ",node_set_m[ans[i]].x,node_set_m[ans[i]].y);
}
printf("%d %d\n",node_set_n[n].x,node_set_n[n].y);
}
return 0;
}

本文介绍了一个关于小狗沿特定轨迹访问最多点的问题,并将其转化为二分图最大匹配问题进行解决,通过匈牙利算法实现了匹配,最终输出小狗能够访问到的最多点数及其路径。
1479

被折叠的 条评论
为什么被折叠?



