poj1034 The dog task 最大匹配

题目讲的是主人出去遛狗。图中有n个景点和m个好玩的地方,主人要沿直线走完n个景点,主人和狗的起点、终点一样,途中狗会离开主人去去一个好玩的地方(每次最多只能一个)并在下一个景点与主人会合,狗的速度是主人的两倍。问最多狗能去几个地方(景点数+能去的最多好玩地方),并且输出狗的行走路线;

构图:把主人走的路段作为X部,景点作为Y部。如果狗在某个路段能到达某个景点就将这两个连线。套用模板求得最大匹配即为狗能到达的最多好玩地方,再加上景点数即可;

Source Code

Problem: 1034   User: 541780774
Memory: 416K   Time: 63MS
Language: G++   Result: Accepted


Source Code

#include<stdio.h>  #include<stdlib.h>  #include<string.h>  #include<math.h>  int nx, ny;             // X的點數目、Y的點數目   int mx[101], my[101];   // X各點的配對對象、Y各點的配對對象   bool vy[101];           // 紀錄Graph Traversal拜訪過的點   bool adj[101][101];     // 精簡過的adjacency matrix      // 以DFS建立一棵交錯樹   bool DFS(int x)   {       for (int y=0; y<ny; ++y)           if (adj[x][y] && !vy[y])           {               vy[y] = true;                  // 找到擴充路徑                 if (my[y] == -1 || DFS(my[y]))                {                  mx[x] = y; my[y] = x;                  return true;                  }           }       return false;   }      int bipartite_matching()   {       // 全部的點初始化為未匹配點。       memset(mx, -1, sizeof(mx));          memset(my, -1, sizeof(my));          // 依序把X中的每一個點作為擴充路徑的端點,       // 並嘗試尋找擴充路徑。       int c = 0;       for (int x=0; x<nx; ++x)   //    if (mx[x] == -1)    // x為未匹配點,這行可精簡。           {               // 開始Graph Traversal               memset(vy, false, sizeof(vy));               if (DFS(x)) c++;           }       return c;   }  main()  {           int i,j,n,m,p[101][2],q[101][2],ans;           double a,b,c;           while(scanf("%d%d",&n,&m)!=EOF)           {             memset(adj,0, sizeof(adj));              for(i=0;i<n;i++)                scanf("%d%d",&p[i][0],&p[i][1]);             for(i=0;i<m;i++)                scanf("%d%d",&q[i][0],&q[i][1]);             for(i=0;i<n-1;i++)             for(j=0;j<m;j++)             {               a=sqrt(pow(p[i][0]-p[i+1][0],2)+pow(p[i][1]-p[i+1][1],2));               b=sqrt(pow(q[j][0]-p[i][0],2)+pow(q[j][1]-p[i][1],2));               c=sqrt(pow(q[j][0]-p[i+1][0],2)+pow(q[j][1]-p[i+1][1],2));               if(b+c<=2*a)                 adj[i][j]=1;             }             nx=n-1;             ny=m;             printf("%d\n",n+bipartite_matching());             printf("%d %d ",p[0][0],p[0][1]);             for(i=0;i<n-1;i++)             {               if(my[mx[i]]==i)                printf("%d %d ",q[mx[i]][0],q[mx[i]][1]);               if(i!=n-2)               printf("%d %d ",p[i+1][0],p[i+1][1]);             }             printf("%d %d\n",p[n-1][0],p[n-1][1]);           }                           system("pause");     } 


 

posted @ 2011-02-12 23:32  CoderZhuang  阅读(268)  评论(0编辑  收藏  举报