POJ 1034

题意:主人带狗去散步,主人走n个点,狗在每个点都会与主人碰头,但其余时候都是各自溜达,除此之外,狗还会去找一些有趣的地方(共m个),每次离开主人狗最多去一个有趣的地方。狗的速度最快是人的两倍,求使得狗到达最多有趣点的方法。

题解:对于人从第i个点到第i+1个点,这条路作为三角形的一边c,然后遍历其他点,若j与这两个点组成的边即为a,b如果a+b<=c则g[i][j]=true,然后做二分图最大匹配,就是狗最多能到的点。

View Code
 1 #include<cstdio>

 2 #include<cstring>

 3 #include<algorithm>

 4 #include<cmath>

 5 using namespace std;

 6 const double eps=1e-8;

 7 bool chk[120],g[120][120];

 8 int n,m,xm[120],ym[120];

 9 bool findpath(int x)

10 {

11     for(int y=0;y<m;y++)

12     {

13         if(g[x][y]&&!chk[y])

14         {

15             chk[y]=true;

16             if(ym[y]==-1||findpath(ym[y]))

17             {

18                 xm[x]=y;

19                 ym[y]=x;

20                 return true;

21             }

22         }

23     }

24     return false;

25 }

26 int maxmatch()

27 {

28     memset(xm,-1,sizeof(xm));

29     memset(ym,-1,sizeof(ym));

30     int ret=0;

31     for(int i=0;i<n;i++)

32     {

33         memset(chk,false,sizeof(chk));

34         if(findpath(i))

35             ret++;

36     }

37     return ret;

38 }

39 int po[120][2],so[120][2];

40 double cal(int x1,int y1,int x2,int y2)

41 {

42     return sqrt((double)((x1-x2)*(x1-x2)+(y1-y2)*(y1-y2)));

43 }

44 bool check(int i,int j,int k)

45 {

46     double a,b,c;

47     a=cal(po[i][0],po[i][1],so[k][0],so[k][1]);

48     b=cal(po[j][0],po[j][1],so[k][0],so[k][1]);

49     c=cal(po[i][0],po[i][1],po[j][0],po[j][1]);

50     if(a+b<2.0*c+eps)

51         return true;

52     else

53         return false;

54 }

55 int main()

56 {

57     int nn;

58     while(scanf("%d%d",&nn,&m)!=EOF)

59     {

60         memset(g,false,sizeof(g));

61         for(int i=0;i<nn;i++)

62             scanf("%d%d",&po[i][0],&po[i][1]);

63         for(int i=0;i<m;i++)

64             scanf("%d%d",&so[i][0],&so[i][1]);

65         n=nn-1;

66         for(int i=0;i<n;i++)

67         {

68             for(int j=0;j<m;j++)

69                 if(check(i,i+1,j))

70                     g[i][j]=true;

71         }

72         printf("%d\n",nn+maxmatch());

73         for(int i=0;i<n;i++)

74         {

75             printf("%d %d ",po[i][0],po[i][1]);

76             if(xm[i]!=-1)

77                 printf("%d %d ",so[xm[i]][0],so[xm[i]][1]);

78         }

79         printf("%d %d\n",po[n][0],po[n][1]);

80     }

81     return 0;

82 }

你可能感兴趣的:(poj)