POJ 3216 Repairing Company (Floyd + 二分图)

题目链接 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     }
View Code

 

posted @ 2015-04-14 21:40  豪气干云  阅读(136)  评论(0编辑  收藏  举报