2060

1 /*
2 建图,然后二分匹配。求最小点覆盖转化为求最大匹配
3 hungarian算法
4 */
5 // include file
6 #include <cstdio>
7 #include <cstdlib>
8 #include <cstring>
9 #include <cmath>
10 #include <cctype>
11 #include <ctime>
12
13 #include <iostream>
14 #include <sstream>
15 #include <fstream>
16 #include <iomanip>
17 #include <bitset>
18 #include <strstream>
19
20 #include <algorithm>
21 #include <string>
22 #include <vector>
23 #include <queue>
24 #include <set>
25 #include <list>
26 #include <functional>
27
28 using namespace std;
29
30 // typedef
31 typedef long long LL;
32 typedef unsigned long long ULL;
33
34 //
35 #define read freopen("in.txt","r",stdin)
36 #define write freopen("out.txt","w",stdout)
37 #define FORi(a,b,c) for(int i=(a);i<(b);i+=c)
38 #define FORj(a,b,c) for(int j=(a);j<(b);j+=c)
39 #define FORk(a,b,c) for(int k=(a);k<(b);k+=c)
40 #define FORp(a,b,c) for(int p=(a);p<(b);p+=c)
41
42 #define FF(i,a) for(int i=0;i<(a);i+++)
43 #define FFD(i,a) for(int i=(a)-1;i>=0;i--)
44 #define Z(a) (a<<1)
45 #define Y(a) (a>>1)
46
47 const double eps = 1e-6;
48 const double INFf = 1e10;
49 const int INFi = 1000000000;
50 const double Pi = acos(-1.0);
51
52 template<class T> inline T sqr(T a){return a*a;}
53 template<class T> inline T TMAX(T x,T y)
54 {
55 if(x>y) return x;
56 return y;
57 }
58 template<class T> inline T TMIN(T x,T y)
59 {
60 if(x<y) return x;
61 return y;
62 }
63 template<class T> inline void SWAP(T &x,T &y)
64 {
65 T t = x;
66 x = y;
67 y = t;
68 }
69 template<class T> inline T MMAX(T x,T y,T z)
70 {
71 return TMAX(TMAX(x,y),z);
72 }
73
74
75 // code begin
76 int T,N,ans;
77 #define MAXN 510
78 vector<int> G[MAXN];
79 int mt[MAXN];
80 bool used[MAXN];
81
82 struct node
83 {
84 int st;
85 int sx;
86 int sy;
87 int ex;
88 int ey;
89 };
90 node mem[MAXN];
91
92 bool hungarian_MM(int i)
93 {
94 FORj(0,G[i].size(),1)
95 {
96 if(!used[ G[i][j] ])
97 {
98 used[ G[i][j] ] = 1;
99 if( mt[ G[i][j] ]==-1 || hungarian_MM( mt[ G[i][j] ] ))
100 {
101 mt[ G[i][j] ] = i;
102 return true;
103 }
104 }
105 }
106 return false;
107 }
108
109 int main()
110 {
111 read;
112 write;
113 int hh,mm;
114 scanf("%d",&T);
115 while(T--)
116 {
117 scanf("%d",&N);
118
119 FORi(0,N,1)
120 {
121 scanf("%d:%d %d %d %d %d",&hh,&mm,&mem[i].sx,&mem[i].sy,&mem[i].ex,&mem[i].ey);
122 mem[i].st = hh*60+mm;
123 }
124
125 FORi(0,N,1)
126 {
127 G[i].clear();
128 }
129
130 //i个旅程起点的时间-j个旅程的到达终点的时间-路上的时间>=1,那么i到j连一条边。。。
131 FORi(0,N,1)
132 {
133 FORj(i+1,N,1)
134 {
135 // 如果i之后能够再次到j,添加进去
136 int end = mem[i].st + abs( mem[i].sx-mem[i].ex ) + abs( mem[i].sy-mem[i].ey );
137 int start = mem[j].st;
138
139 if( abs( mem[i].ex-mem[j].sx ) + abs( mem[i].ey-mem[j].sy ) < start-end )
140 {
141 // add
142 G[i].push_back(j);
143 }
144 }
145 }
146
147
148 memset(mt,-1,sizeof(int)*MAXN);
149 ans = 0;
150 FORi(0,N,1)
151 {
152 memset(used,0,sizeof(bool)*MAXN);
153 if( hungarian_MM(i))
154 {
155 ans ++;
156 }
157 }
158 printf("%d\n",N-ans);
159 }
160 return 0;
161 }
posted @ 2011-03-04 19:56  AC2012  阅读(259)  评论(0编辑  收藏  举报