二分图最大匹配(匈牙利算法) UVA 670 The dog task

 

题目传送门

 1 /*  2  题意:bob按照指定顺序行走,他的狗可以在他到达下一个点之前到一个景点并及时返回,问狗最多能走多少个景点  3  匈牙利算法:按照狗能否顺利到一个景点分为两个集合,套个模板  4 */  5 #include <cstdio>  6 #include <algorithm>  7 #include <cstring>  8 #include <cmath>  9 #include <vector>  10 using namespace std;  11  12 const int MAXN = 1e2 + 10;  13 const int INF = 0x3f3f3f3f;  14 struct P  15 {  16 int x, y;  17 double nxt;  18 }bob[MAXN], dog[MAXN];  19 double d[MAXN][MAXN];  20 bool vis[MAXN];  21 int lk[MAXN];  22 int lk2[MAXN];  23 vector<int> G[MAXN];  24  25 double get_dis(int x1, int y1, int x2, int y2)  26 {  27 return sqrt ((1.0) * ((x1-x2) * (x1-x2) + (y1-y2) * (y1-y2)));  28 }  29  30 bool DFS(int u)  31 {  32 for (int i=0; i<G[u].size (); ++i)  33  {  34 int v = G[u][i];  35 if (!vis[v])  36  {  37 vis[v] = true;  38 if (lk[v] == -1 || DFS (lk[v]))  39  {  40 lk[v] = u; lk2[u] = v; return true;  41  }  42  }  43  }  44  45 return false;  46 }  47  48 void hungary(int n)  49 {  50 int res = 0; memset (lk, -1, sizeof (lk)); memset (lk2, -1, sizeof (lk2));  51 for (int i=1; i<n; ++i)  52  {  53 memset (vis, false, sizeof (vis));  54 if (DFS (i)) res++;  55  }  56  57 printf ("%d\n", n + res);  58 for (int i=1; i<n; ++i)  59  {  60 printf ("%d %d ", bob[i].x, bob[i].y);  61 if (lk2[i] != -1) printf ("%d %d ", dog[lk2[i]].x, dog[lk2[i]].y);  62  }  63 printf ("%d %d\n", bob[n].x, bob[n].y);  64 }  65  66 int main(void) //UVA 670 The dog task  67 {  68 // freopen ("UVA_670.in", "r", stdin);  69  70 int t; scanf ("%d", &t);  71 while (t--)  72  {  73 int n, m; scanf ("%d%d", &n, &m);  74 for (int i=1; i<=n; ++i)  75  {  76 scanf ("%d%d", &bob[i].x, &bob[i].y); G[i].clear ();  77  }  78 for (int i=1; i<=m; ++i)  79  {  80 scanf ("%d%d", &dog[i].x, &dog[i].y);  81  }  82  83 for (int i=1; i<=n; ++i)  84  {  85 for (int j=1; j<=m; ++j)  86  {  87 d[i][j] = get_dis (bob[i].x, bob[i].y, dog[j].x, dog[j].y);  88  }  89  }  90  91 for (int i=1; i<n; ++i)  92  {  93 bob[i].nxt = get_dis (bob[i].x, bob[i].y, bob[i+1].x, bob[i+1].y);  94  }  95  96 for (int i=1; i<n; ++i)  97  {  98 for (int j=1; j<=m; ++j)  99  { 100 if (d[i][j] + d[i+1][j] <= 2 * bob[i].nxt) G[i].push_back (j); 101  } 102  } 103 104  hungary (n); 105 if (t) puts (""); 106  } 107 108 return 0; 109 }

 

你可能感兴趣的:(task)