[题目来源]:POJ2060
[关键字]:二分图最小路径覆盖
[题目大意]:给出一系列出租车客人的时间表,问最少需多少人才能满足每一位顾客。
//=====================================================================================================
[分析]:如果以每个顾客时间看成一个点,一个出租车在它从出发地出发到到达下一个顾客开始第所用时间满足约束条件,则就在这两个任务间连一条边。此时需要求的就是要覆盖所有的点所需的最小的路径数=最大独立集=所有点-最大匹配。
[代码]:
1 type
2 rec = record
3 sx, sy, ex, ey: longint;
4 end;
5 var
6 tc, n: longint;
7 map: array[0..1010,0..1010] of boolean;
8 b: array[0..1000] of boolean;
9 t: array[0..1000] of string[30];
10 link: array[0..1000] of longint;
11 a: array[0..2020] of rec;
12
13 function cha(s1, s2: string):longint;
14 var
15 h1, h2, m1, m2, sum: longint;
16 begin
17 h1 := (ord(s1[1])-48)*10+ord(s1[2])-48;
18 h2 := (ord(s2[1])-48)*10+ord(s2[2])-48;
19 m1 := (ord(s1[4])-48)*10+ord(s1[5])-48;
20 m2 := (ord(s2[4])-48)*10+ord(s2[5])-48;
21 //writeln(s1,' ',s2,' ',h1,' ',h2,' ',m1,' ',m2);
22 sum := (h2-h1)*60+m2-m1;
23 exit(sum);
24 end;
25
26 procedure init;
27 var
28 i, j, t1, t2: longint;
29 s: string;
30 begin
31 readln(n);
32 for i := 1 to n do
33 begin
34 readln(s);
35 t[i] := copy(s,1,pos(' ',s)-1);
36 delete(s,1,pos(' ',s));
37 val(copy(s,1,pos(' ',s)-1),a[i].sx);
38 delete(s,1,pos(' ',s));
39 val(copy(s,1,pos(' ',s)-1),a[i].sy);
40 delete(s,1,pos(' ',s));
41 val(copy(s,1,pos(' ',s)-1),a[i].ex);
42 delete(s,1,pos(' ',s));
43 val(s,a[i].ey);
44 //writeln(t[i],' ',a[i].sx,' ',a[i].sy,' ',a[i].ex,' ',a[i].ey);
45 end;
46 fillchar(map,sizeof(map),false);
47 for i := 1 to n do
48 for j := i+1 to n do
49 begin
50 t1 := cha(t[i],t[j]);
51 t2 := abs(a[i].sx-a[i].ex)+abs(a[i].sy-a[i].ey);
52 t2 := t2+abs(a[i].ex-a[j].sx)+abs(a[i].ey-a[j].sy);
53 //writeln(i,' ',j,' ',t1,' ',t2);
54 if t2 <= t1-1 then
55 begin
56 map[i,j] := true;
57 // map[j,i] := true;
58 end;
59 end;
60 {for i := 1 to n do
61 for j := 1 to n do
62 writeln(i,' ',j,' ',map[i,j]);}
63 end;
64
65 function dfs(k: longint):boolean;
66 var
67 i: longint;
68 begin
69 for i := 1 to n do
70 if (map[k,i]) and (not b[i]) then
71 begin
72 b[i] := true;
73 if (link[i] = 0) or (dfs(link[i])) then
74 begin
75 link[i] := k;
76 exit(true);
77 end;
78 end;
79 exit(false);
80 end;
81
82 procedure work;
83 var
84 i, max: longint;
85 begin
86 max := 0;
87 fillchar(link,sizeof(link),0);
88 for i := 1 to n do
89 begin
90 fillchar(b,sizeof(b),false);
91 if dfs(i) then inc(max);
92 end;
93 //writeln(n,' ',max);
94 writeln(n-max);
95 end;
96
97 begin
98 readln(tc);
99 while tc > 0 do
100 begin
101 init;
102 work;
103 dec(tc);
104 end;
105 end.