题目链接 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,Di
输出 最少的修理工
思路分析
分析:首先根据 地图 求出来 任意两个块之间的最短路径, 之后 根据 任务,求任务的二分图最大匹配,得出 最小路径覆盖即可;
如何建二分图:如果 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