这是一道描述非常不清楚的题目
首先解释一下,题目中的ti是任务开始时间不是结束时间,
然后维修人员可以理解为可以再任意时间从公司出发;
好,首先不难想到用floyd预处理一下;
然后我们把每个任务看成一个点,显然有些维修员完成一个任务后还可以接着完成别的任务;
这样我们就可以构造出一张有向无环图;
考虑到每个任务这需要我们做一次且仅一次,并且现在我们要求最少的人去覆盖所有的点;
不难想到最小路径覆盖,构造二分图求解即可
1 const inf=20000007; 2 type node=record 3 next,point:longint; 4 end; 5 6 var edge:array[0..200010] of node; 7 p,cx,cy,d,s,w:array[0..600] of longint; 8 v:array[0..600] of boolean; 9 a:array[0..600,0..600] of longint; 10 len,ans,i,j,n,m,k:longint; 11 12 function min(a,b:longint):longint; 13 begin 14 if a>b then exit(b) else exit(a); 15 end; 16 17 procedure add(x,y:longint); 18 begin 19 inc(len); 20 edge[len].point:=y; 21 edge[len].next:=p[x]; 22 p[x]:=len; 23 end; 24 25 function find(x:longint):longint; 26 var i,y:longint; 27 begin 28 i:=p[x]; 29 while i<>-1 do 30 begin 31 y:=edge[i].point; 32 if not v[y] then 33 begin 34 v[y]:=true; 35 if (cy[y]=-1) or (find(cy[y])=1) then 36 begin 37 cx[x]:=y; 38 cy[y]:=x; 39 exit(1); 40 end; 41 end; 42 i:=edge[i].next; 43 end; 44 exit(0); 45 end; 46 47 begin 48 readln(n,m); 49 while (n<>0) do 50 begin 51 len:=0; 52 fillchar(p,sizeof(p),255); 53 for i:=1 to n do 54 for j:=1 to n do 55 begin 56 read(a[i,j]); 57 if a[i,j]=-1 then a[i,j]:=inf; 58 end; 59 for k:=1 to n do 60 for i:=1 to n do 61 if (i<>k) then 62 for j:=1 to n do 63 if (i<>j) and (j<>k) then 64 a[i,j]:=min(a[i,j],a[i,k]+a[k,j]); 65 for i:=1 to m do 66 readln(w[i],s[i],d[i]); 67 for i:=1 to m do 68 for j:=1 to m do 69 begin 70 if i=j then continue; 71 if a[w[i],w[j]]+s[i]+d[i]<=s[j] then add(i,j); 72 end; 73 ans:=0; 74 fillchar(cx,sizeof(cx),255); 75 fillchar(cy,sizeof(cy),255); 76 for i:=1 to m do 77 if cx[i]=-1 then 78 begin 79 fillchar(v,sizeof(v),false); 80 ans:=ans+find(i); 81 end; 82 writeln(m-ans); 83 readln(n,m); 84 end; 85 end.