You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

72 lines
2.0 KiB

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

#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;
}