poj3216

这是一道描述非常不清楚的题目

首先解释一下,题目中的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.
View Code

 

转载于:https://www.cnblogs.com/phile/p/4473240.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值