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

来源:互联网 发布:dns解析域名到端口号 编辑:程序博客网 时间:2024/06/10 19:57

POJ 3216 Repairing Company

题目链接

题意:有m项任务,每项任务的起始时间,持续时间,和它所在的block已知,且往返每对相邻block之间的时间也知道,问最少需要多少个工人才能完成任务,即x最少是多少

思路:先floyd求出每两个block之间的最小距离,然后就是最小路径覆盖问题,一个任务之后能赶到另一个任务就建边

代码:

#include <cstdio>#include <cstring>#include <algorithm>#include <vector>using namespace std;const int N = 25;const int M = 205;const int INF = 0x3f3f3f3f;int n, m, q[N][N];vector<int> g[M];int in[M], s[M], d[M];bool judge(int i, int j) {return s[i] + d[i] + q[in[i]][in[j]] <= s[j];}int left[M], vis[M];bool dfs(int u) {for (int i = 0; i < g[u].size(); i++) {int v = g[u][i];if (vis[v]) continue;vis[v] = 1;if (left[v] == -1 || dfs(left[v])) {left[v] = u;return true;}}return false;}int hungary() {int ans = 0;memset(left, -1, sizeof(left));for (int i = 0; i < m; i++) {memset(vis, 0, sizeof(vis));if (dfs(i)) ans++;}return ans;}int main() {while (~scanf("%d%d", &n, &m) && n) {for (int i = 1; i <= n; i++)for (int j = 1; j <= n; j++) {scanf("%d", &q[i][j]);if (q[i][j] == -1) q[i][j] = INF;}for (int k = 1; k <= n; k++) {for (int i = 1; i <= n; i++) {for (int j = 1; j <= n; j++) {q[i][j] = min(q[i][j], q[i][k] + q[k][j]);}}}for (int i = 0; i < m; i++) {g[i].clear();scanf("%d%d%d", &in[i], &s[i], &d[i]);for (int j = 0; j < i; j++) {if (judge(i, j))g[i].push_back(j);if (judge(j, i))g[j].push_back(i);}}printf("%d\n", m - hungary());}return 0;}


1 0
原创粉丝点击