POJ 3216 Repairing Company

题目链接 http://poj.org/problem?id=3216

题目解释

题意:莉莉是一家维修公司,服务这个城市的 Q 块。有一天,公司收到M修复任务,其中第 i 个发生在Pi块,对任何修理工的到来的最后到来期限的Ti,就是它的起始时间,并需要一个修理工  Di  时间完成。修理工完成当前单个任务,必须在移动(移动到下一个块需要消耗时间)到下一个完成下一个任务。有地图在手,莉莉想知道最少的修理工,才能够完成金今天所有的任务。

输入:首先输入两个数 Q, M, 代表有 Q 个块, M个任务,下面输入 QxQ 个数,即一个矩阵,Qij 表示第i个块 到 第j个块的 时间,如果是-1,则表示他们之间没有路;

接下来是 M 行,每行3 个数,分别是Pi, Ti,D

输出 最少的修理工

思路分析

分析:首先根据 地图 求出来 任意两个块之间的最短路径, 之后 根据 任务,求任务的二分图最大匹配,得出 最小路径覆盖即可;

如何建二分图:如果 Di + Qij <= Tj,即当前任务结束时间加上路径时间不大于下一个任务开始时间 即建边

代码:

 1 #include <cstdio>
 2 #include <cstdlib>
 3 #include <cstring>
 4 #include <cctype>
 5 #include <cmath>
 6 #include <algorithm>
 7 #include <vector>
 8 #include <queue>
 9 #include <stack>
10 #include <map>
11
12 using namespace std;
13
14 const int INF=0x3f3f3f3f;
15 #define maxn 300
16 int edge[maxn][maxn], q, m;
17 bool visit[maxn], g[maxn][maxn];
18 int match[maxn];
19 struct Task
20 {
21     int id, s, e;
22 }task[maxn];
23 void Floyd()
24 {
25     for(int i = 1; i <= q; i++)
26     {
27         for(int j = 1; j <= q; j++)
28         {
29             for(int k = 1; k <= q; k++)
30             {
31                 if (edge[j][i] + edge[i][k] < edge[j][k])
32                     edge[j][k] = edge[j][i] + edge[i][k];
33             }
34         }
35     }
36 }
37
38 bool dfs(int num)
39 {
40     int u = task[num].id, t1 = task[num].s, d1 = task[num].e;
41     for(int i = 0; i < m; i++)
42     {
43         int v = task[i].id, t2 = task[i].s, d2 = task[i].e;
44         //printf("edge = %d m = %d d1 = %d t2 = %d\n", edge[u][v], m, d1, t2);
45         if (edge[u][v]!=INF && !visit[i] && t1+d1+edge[u][v]<=t2)
46         {
47             //puts("hehe");
48             visit[i] = true;
49             if(match[i] == -1 || dfs(match[i]))
50             {
51                 match[i] = num;
52                 return true;
53             }
54         }
55     }
56     return false;
57 }
58 int Hungary()
59 {
60     int ans = 0;
61     memset(match, -1, sizeof(match));
62     for(int i = 0; i < m; i++)
63     {
64         memset(visit, false, sizeof(visit));
65         if(dfs(i))
66             ans++;
67         //printf("ans = %d", ans);
68     }
69     return ans;
70 }
71 int main()
72 {
73     int p, d, t;
74     while(scanf("%d %d", &q, &m) && q+m)
75     {
76         for(int i = 1; i <= q; i++)
77         {
78             for(int j = 1; j <= q; j++)
79             {
80                 scanf("%d", &edge[i][j]);
81                 if(edge[i][j] == -1)
82                     edge[i][j] = INF;
83             }
84         }
85         Floyd();
86         for(int i = 0; i < m; i++)
87         {
88             scanf("%d %d %d", &p, &t, &d);
89             task[i].id = p; task[i].s = t; task[i].e = d;
90         }
91         printf("%d\n", m - Hungary());
92     }

时间: 2024-10-29 04:28:56

POJ 3216 Repairing Company的相关文章

POJ 3216 Repairing Company【Floyd + 最小路径覆盖】

大意: 有n个任务,每个任务有三个属性:所在街区,最晚开始时间,执行需要时间 告诉你一个矩阵代表街区间到达时间 告诉你每个任务的三个属性 问最少需要多少人去完成所有任务 分析: floyd处理处任意两个街区的到达时间 拆点   左边集合为n个任务    右边集合跟左边相同 i任务能够到达j任务就从左集合引一条边到右集合 求最小路径覆盖 最小路径覆盖 = n - 最大匹配 代码: 1 #include <iostream> 2 #include <cstdio> 3 #include

POJ 3216 Repairing Company(最小路径覆盖)

POJ 3216 Repairing Company 题目链接 题意:有m项任务,每项任务的起始时间,持续时间,和它所在的block已知,且往返每对相邻block之间的时间也知道,问最少需要多少个工人才能完成任务,即x最少是多少 思路:先floyd求出每两个block之间的最小距离,然后就是最小路径覆盖问题,一个任务之后能赶到另一个任务就建边 代码: #include <cstdio> #include <cstring> #include <algorithm> #i

POJ 3216 Repairing Company(二分图匹配)

题意:给定n条街道,用一个矩阵描述两两之间的距离,m个任务,p,t,d分别为所在街道.任务起始时间.任务结束时间,求完成所有任务所需最少人数: 思路:先用floyd处理两两间最短路,然后,若完成i任务的人能够完成j任务,则在i,j间建一条边,所需人数为总任务数减最大匹配数:匈牙利算法: #include<cstdio> #include<cstring> #include<algorithm> using namespace std; #define INF 0x3f3

POJ - 3216 Repairing Company 二分图 最小路径覆盖

题目大意:有一个人开了一间维修店.某天,该维修店接收到了Q个任务,这Q个任务分布在M个城市中.每个任务有三个值,分别是所在城市,起始时间,维修时间. 现在给出M个城市的路线图,路线对应的是从某城市到某城市的所需时间. 问至少要派多少个维修人员才能完成这Q个任务 解题思路:现将能联通的城市联通起来,用floyd求出城市之间的时间数 接着就要找关系了,如果 起始时间 + 维修时间 + 两个城市来往的时间 <= 另外一个任务的起始时间 就表示该任务做完后可以接着做下一个任务,这样关系就明确了 现在要求

(floyd+匈牙利算法) poj 3216

O - Repairing Company Time Limit:1000MS     Memory Limit:131072KB     64bit IO Format:%I64d & %I64u Submit Status Practice POJ 3216 Description Lily runs a repairing company that services the Q blocks in the city. One day the company receives M repai

POJ 3216 最小路径覆盖+floyd

Repairing Company Time Limit: 1000MS   Memory Limit: 131072K Total Submissions: 6646   Accepted: 1788 Description Lily runs a repairing company that services the Q blocks in the city. One day the company receives M repair tasks, the ith of which occu

搜索+剪枝 POJ 1416 Shredding Company

POJ 1416 Shredding Company Time Limit: 1000MS   Memory Limit: 10000K Total Submissions: 5231   Accepted: 2964 Description You have just been put in charge of developing a new shredder for the Shredding Company Although a "normal" shredder would

poj 1416 -- Shredding Company

Shredding Company Time Limit: 1000MS   Memory Limit: 10000K Total Submissions: 4114   Accepted: 2324 Description You have just been put in charge of developing a new shredder for the Shredding Company Although a "normal" shredder would just shre

Repairing Company(poj 3216)

题目大意: 有Q个地点,告诉你Q个地点之间的相互距离(从i地点赶到j地点需要的时间).有M项任务, 给你M项任务所在的地点block.开始时间start和任务完成需要时间time.一个工人只有在 他准备完成的下一项任务开始之前完成手上的任务,然后在下一项任务开始之前赶到下一项 任务的地点,才能完成这两项任务.问:最少需要多少个工人来完成这M项任务. /* 对于这类二分图的最小路径覆盖,我是这么理解的: 那这道题来说,我们可以先假设一共需要m个工人,然后经过二分图匹配, 每匹配一对,说明有两项任务