Poj 3216 Repairing Company
Question Link
There are m tasks. The start time, duration, and block of each task are known, and the time between each pair of adjacent blocks is also known, ask the minimum number of workers required to complete the task, that is, the minimum number of workers x.
Idea: first, Floyd is used to find the minimum distance between each block, and then the minimum path overwrite problem. After a task is executed, it can be created when it reaches another task.
Code:
#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;}
Poj 3216 Repairing Company (minimum path overwrite)