这是一道描述非常不清楚的题目
首先解释一下,题目中的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 begin14 if a>b then exit(b) else exit(a);15 end;16 17 procedure add(x,y:longint);18 begin19 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 begin28 i:=p[x];29 while i<>-1 do30 begin31 y:=edge[i].point;32 if not v[y] then33 begin34 v[y]:=true;35 if (cy[y]=-1) or (find(cy[y])=1) then36 begin37 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 begin48 readln(n,m);49 while (n<>0) do50 begin51 len:=0;52 fillchar(p,sizeof(p),255);53 for i:=1 to n do54 for j:=1 to n do55 begin56 read(a[i,j]);57 if a[i,j]=-1 then a[i,j]:=inf;58 end;59 for k:=1 to n do60 for i:=1 to n do61 if (i<>k) then62 for j:=1 to n do63 if (i<>j) and (j<>k) then64 a[i,j]:=min(a[i,j],a[i,k]+a[k,j]);65 for i:=1 to m do66 readln(w[i],s[i],d[i]);67 for i:=1 to m do68 for j:=1 to m do69 begin70 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 do77 if cx[i]=-1 then78 begin79 fillchar(v,sizeof(v),false);80 ans:=ans+find(i);81 end;82 writeln(m-ans);83 readln(n,m);84 end;85 end.