UVALive3126 Taxi Cab Scheme —— 最小路径覆盖

题目链接:https://vjudge.net/problem/UVALive-3126

 

 

 

 

题解:

最小路径覆盖:即在图中找出尽量少的路径,使得每个结点恰好只存在于一条路径上。其中单独一个点也可以是一条路径。

1.如果接完x之后能继续接y,那么x、y之间连一条有向边:x-->y。

2.利用匈牙利算法,求出最大匹配数m。假设总共有n个客人,那么结果就是:n-m。即:

最小路径覆盖 = 总体 - 最大匹配数 。  为何?

答:每存在一个配对,就意味着有一个乘客可以坐别人打过的车,而不需要再另设一辆车去接他。所以,有几个配对,就能免去几辆车,所以实际需要的车就是n-m。又因为是“最大”匹配数, 即m最大, 所以n-m最小。所以所需的车也最少。抽象化,所以:最小路径覆盖 = 总体 - 最大匹配数。

 

 

代码如下:

 1 #include <iostream>
 2 #include <cstdio>
 3 #include <cstring>
 4 #include <cstdlib>
 5 #include <string>
 6 #include <vector>
 7 #include <map>
 8 #include <set>
 9 #include <queue>
10 #include <sstream>
11 #include <algorithm>
12 using namespace std;
13 const int INF = 2e9;
14 const int MOD = 1e9+7;
15 const int MAXN = 1e3+10;
16 
17 int n;
18 int M[MAXN][MAXN], link[MAXN];
19 bool vis[MAXN];
20 
21 struct Node
22 {
23     int time[2], sor[2], des[2];
24 }a[MAXN];
25 
26 bool dfs(int u)
27 {
28     for(int i = 1; i<=n; i++)
29     if(M[u][i] && !vis[i])
30     {
31         vis[i] = true;
32         if(link[i]==-1 || dfs(link[i]))
33         {
34             link[i] = u;
35             return true;
36         }
37     }
38     return false;
39 }
40 
41 int hungary()
42 {
43     int ret = 0;
44     memset(link, -1, sizeof(link));
45     for(int i = 1; i<=n; i++)
46     {
47         memset(vis, 0, sizeof(vis));
48         if(dfs(i)) ret++;
49     }
50     return ret;
51 }
52 
53 bool judge(Node x, Node y)
54 {
55     int t1 = x.time[0]*60+x.time[1];
56     int t2 = y.time[0]*60+y.time[1];
57     int dis1 = abs(x.des[0]-x.sor[0]) + abs(x.des[1]-x.sor[1]);
58     int dis2 = abs(y.sor[0]-x.des[0]) + abs(y.sor[1]-x.des[1]);
59     return (t1+dis1+dis2+1<=t2);
60 }
61 
62 int main()
63 {
64     int T;
65     scanf("%d", &T);
66     while(T--)
67     {
68         scanf("%d", &n);
69         for(int i = 1; i<=n; i++)
70         {
71             scanf("%d:%d", &a[i].time[0], &a[i].time[1]);
72             scanf("%d%d%d%d", &a[i].sor[0], &a[i].sor[1], &a[i].des[0], &a[i].des[1]);
73         }
74 
75         memset(M, 0, sizeof(M));
76         for(int i = 1; i<=n; i++)
77         for(int j = 1; j<=n; j++)
78             if(i!=j && judge(a[i], a[j]))
79                 M[i][j] = 1;
80 
81         int cnt = hungary();
82         printf("%d\n", n-cnt);
83     }
84 }
View Code

 

posted on 2017-11-07 12:17  h_z_cong  阅读(299)  评论(0编辑  收藏  举报

导航