UVALive3126 Taxi Cab Scheme —— 最小路徑覆蓋

題目連接:https://vjudge.net/problem/UVALive-3126ios

 

 

 

 

題解:算法

最小路徑覆蓋:即在圖中找出儘可能少的路徑,使得每一個結點剛好只存在於一條路徑上。其中單獨一個點也能夠是一條路徑。ide

1.若是接完x以後能繼續接y,那麼x、y之間連一條有向邊:x-->y。spa

2.利用匈牙利算法,求出最大匹配數m。假設總共有n個客人,那麼結果就是:n-m。即:.net

最小路徑覆蓋 = 整體 - 最大匹配數 。  爲什麼?code

答:每存在一個配對,就意味着有一個乘客能夠坐別人打過的車,而不須要再另設一輛車去接他。因此,有幾個配對,就能免去幾輛車,因此實際須要的車就是n-m。又由於是「最大」匹配數, 即m最大, 因此n-m最小。因此所需的車也最少。抽象化,因此:最小路徑覆蓋 = 整體 - 最大匹配數。blog

 

 

代碼以下:get

 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
相關文章
相關標籤/搜索