//目录

LA 3126 出租车

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

题意:有m个客人,位于不同的位置,去一些地方,出发的时间给出,要一些出租车去接,但是,每辆出租车要在出发前一分钟要到,问:最少要几辆出租车;

分析:最少路径覆盖(在图中找尽量少的路径,使得每个节点恰好在一条路径上)

建图: 一个点拆成 i i',i->j 就连一条边到 j';

答案是 n - 最大匹配;

证明:之前有证明过,很有意思;

 

这里,就是从一个接完客人到另下一个客人,是否可以接到,能就连一条边;

 1 #include <cstdio>
 2 #include <cstring>
 3 #include <vector>
 4 #include <algorithm>
 5 using namespace std;
 6 
 7 const int maxn = 500 + 5; // 单侧顶点的最大数目
 8 
 9 struct BPM {
10     int n,m;
11     vector<int> G[maxn];
12     int left[maxn];
13     bool T[maxn];
14 
15     int right[maxn];
16     bool S[maxn];
17 
18     void init(int n,int m) {
19         this->n = n;
20         this->m = m;
21         for(int i=0; i<n; i++)
22             G[i].clear();
23     }
24 
25     void AddEdge(int u,int v) {
26         G[u].push_back(v);
27     }
28 
29     bool match(int u) {
30         S[u] = true;
31         for(int i=0; i<G[u].size(); i++) {
32             int v = G[u][i];
33             if(!T[v]) {
34                 T[v] = true;
35                 if(left[v]==-1||match(left[v])) {
36                     left[v] = u;
37                     right[u] = v;
38                     return true;
39                 }
40             }
41         }
42         return false;
43     }
44 
45     int solve() {
46         memset(left,-1,sizeof(left));
47         memset(right,-1,sizeof(right));
48         int ans = 0;
49         for(int u=0; u<n; u++) {
50             memset(S,0,sizeof(S));
51             memset(T,0,sizeof(T));
52             if(match(u))
53                 ans++;
54         }
55         return ans;
56     }
57 
58 } sol;
59 
60 
61 int x1[maxn], y1[maxn], x2[maxn], y2[maxn], t1[maxn], t2[maxn];
62 
63 int dist(int a, int b, int c, int d) {
64     return abs(a-c) + abs(b-d);
65 }
66 
67 int main() {
68     int T;
69     scanf("%d", &T);
70     while(T--) {
71         int n;
72         scanf("%d", &n);
73         for(int i = 0; i < n; i++) {
74             int h, m;
75             scanf("%d:%d%d%d%d%d", &h, &m, &x1[i], &y1[i], &x2[i], &y2[i]);
76             t1[i] = h*60+m;
77             t2[i] = t1[i] + dist(x1[i], y1[i], x2[i], y2[i]);
78         }
79         sol.init(n, n);
80         for(int i = 0; i < n; i++)
81             for(int j = i+1; j < n; j++)
82                 if(t2[i] + dist(x2[i], y2[i], x1[j], y1[j]) < t1[j])
83                     sol.AddEdge(i,j);
84         printf("%d\n", n - sol.solve());
85     }
86     return 0;
87 }
View Code

 

posted @ 2017-05-05 21:58  小草的大树梦  阅读(218)  评论(0编辑  收藏  举报