Files
python/TangDou/AcWing/ErFenTu/POJ3216.cpp
HuangHai 1f397eca87 'commit'
2025-08-30 18:35:01 +08:00

72 lines
2.0 KiB
C++
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

#include <iostream>
#include <algorithm>
#include <queue>
#include <map>
#include <cstring>
#include <vector>
#include <stack>
#include <cstdio>
using namespace std;
const int N = 25;
const int M = 205;
const int INF = 0x3f3f3f3f;
struct Task {
int id; // 维修站
int cost; // 花费时间
int st; // 起始时间
} task[M];
int m, n, g[N][N];
// 匈牙利算法
int match[M], st[M];
bool dfs(int u) {
for (int i = 0; i < m; i++) {
if (st[i]) continue;
// 这里很妙,不是真的把图建出来,而是直接利用原来的邻接矩阵,通过条件判断来决策,减少了代码!
if (task[u].st + task[u].cost + g[task[u].id][task[i].id] > task[i].st) continue;
st[i] = 1;
if (match[i] == -1 || dfs(match[i])) {
match[i] = u;
return 1;
}
}
return 0;
}
int main() {
#ifndef ONLINE_JUDGE
freopen("POJ3216.in", "r", stdin);
#endif
while (~scanf("%d%d", &n, &m) && n + m) {
// 题目中给出的不可达值为-1,因为要求最短路,所以设置为INF
for (int i = 1; i <= n; i++)
for (int j = 1; j <= n; j++) {
scanf("%d", &g[i][j]);
if (g[i][j] == -1) g[i][j] = INF;
}
// Floyd求任意两点间最短距离
for (int k = 1; k <= n; k++)
for (int i = 1; i <= n; i++)
for (int j = 1; j <= n; j++)
g[i][j] = min(g[i][j], g[i][k] + g[k][j]);
// m个任务
for (int i = 0; i < m; i++)
scanf("%d%d%d", &task[i].id, &task[i].st, &task[i].cost);
// Hungary
memset(match, -1, sizeof match);
int res = 0;
for (int i = 0; i < m; i++) { // 枚举所个任务
memset(st, 0, sizeof st);
if (dfs(i)) res++;
}
// 输出结果
printf("%d\n", m - res);
}
return 0;
}