您的位置:首页 > 其它

ZJU2039 The Dog Task - 二部图最大匹配

2008-04-28 16:23 357 查看
题目大意:

Bob带着他的Dog外出散步,Bob速度固定且依次沿着n个点行走,分别用(Xi,Yi)表示。Dog的速度可以达到Bob的2倍。在路途中有m个地点是Dog喜欢玩耍的地方,用(Xi',Yi')表示。Dog和Bob同时从第一个点X1,Y1出发,Dog在路途中跑去玩耍,但是必须在Bob到达第二个点X2,Y2时赶回来和Bob碰面。每次离开Bob,Dog最多只能去一个地方玩耍,以前去过的地方Dog不会再去。输入Bob的行走路线的n个点,和Dog喜欢玩耍的m个点,要求Dog最多能去多少地方玩耍并输出他的路线。

分析:

网上有些题目分类说这是个计算几何题。>_<显然,做分类的这个家伙一定没有读过题。

Bob路线上的n个点可以看作是n-1条线段。对于每条线段来说,只要Dog从起点出发去某个地点P玩耍后回到终点的总路程s,大于这条线段的长度,那么Dog就可以去P玩耍。

用n-1条线段和m个玩耍地点做一个二部图,若g[i][j]有边相连,表示行走第i条线段时可以去地点j玩耍。然后求这个二部图g[n-1][m]的最大匹配即可。

----------------------------------------------------

/*
ZJU2039 The Dog Task
*/

#include <stdio.h>
#include <math.h>
#include <memory.h>
#define clr(a) memset(a,0,sizeof(a))

#define N 105

typedef struct{
int x,y;
}Point;

//functions
double distance(Point p1,Point p2){
return sqrt( (p1.x-p2.x)*(p1.x-p2.x)
+(p1.y-p2.y)*(p1.y-p2.y));
}

int find(int i,int m,int g[]
,int mat[],int tmat[]){
int v,j;
for(j=0;j<m;j++)
if(g[i][j]&&tmat[j]==0){
tmat[j]=1;v=mat[j];
mat[j]=i;
if(v==-1||find(v,m,g,mat,tmat)) return 1;
mat[j]=v;
}
return 0;
}

int match(int g[]
,int n,int m,int mat[]){
int i,k=0;
int tmat
;
for(i=0;i<m;i++) mat[i]=-1;
for(i=0;i<n;i++){
memset(tmat,0,sizeof(tmat));
k+=find(i,m,g,mat,tmat);
}
return k;
}

int main()
{
int i,j,k,m,n,T;
double s,s1,s2;
Point Bob
;
Point tree
;
int g

;
int mat
;

scanf("%d",&T);
while(T--){

//input
scanf("%d%d",&n,&m);
for(i=0;i<n;i++)
scanf("%d%d",&Bob[i].x,&Bob[i].y);
for(i=0;i<m;i++)
scanf("%d%d",&tree[i].x,&tree[i].y);

//creat map
clr(g);
for(i=0;i<n-1;i++){
s=distance(Bob[i],Bob[i+1])*2.0;
for(j=0;j<m;j++){
s1=distance(Bob[i],tree[j]);
s2=distance(Bob[i+1],tree[j]);
if(s>s1+s2) g[j][i]=1;
}
}

//match
k=match(g,m,n-1,mat);

//output
printf("%d/n",n+k);
for(i=0;i<n-1;i++){
printf("%d %d ",Bob[i].x,Bob[i].y);
if(mat[i]!=-1)
printf("%d %d ",tree[mat[i]].x,tree[mat[i]].y);
}
printf("%d %d/n",Bob[i].x,Bob[i].y);

if(T) puts("");
}

return 0;
}

/*

2

4 5
1 4 5 7 5 2 -2 4
-4 -2 3 9 1 2 -1 3 8 -3

*/
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: