1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77
| #include <cstdio> #include <cstring>
int min(int a, int b) { return a < b ? a : b; }
static const int Q = 25; static const int M = 405; int mp[Q][Q], p[M], t[M], d[M]; int nume, h[M]; struct Edge { int v, f, nxt; } e[M * M << 1];
void add_edge(int u, int v, int f) { e[++ nume] = (Edge) { v, f, h[u] }, h[u] = nume; e[++ nume] = (Edge) { u, 0, h[v] }, h[v] = nume; }
namespace flow { int S, T, g[M], dist[M], que[M], gap[M];
bool bfs() { memcpy(g, h, sizeof h); memset(dist, 0x3f, sizeof dist), memset(gap, 0, sizeof gap); int qb = 0, qe = 1; dist[T] = 0, que[0] = T, ++ gap[0]; while (qb < qe) { int u = que[qb ++]; for (int i = g[u]; i; i = e[i].nxt) if (e[i ^ 1].f && dist[e[i].v] > dist[u] + 1) dist[e[i].v] = dist[u] + 1, que[qe ++] = e[i].v, ++ gap[dist[e[i].v]]; } return dist[S] < 1e9; }
int dfs(int t, int low) { if (t == T) return low; int used = 0; for (int &i = g[t]; i; i = e[i].nxt) if (e[i].f && dist[e[i].v] == dist[t] - 1) { int flow = dfs(e[i].v, min(e[i].f, low - used)); if (flow) e[i].f -= flow, e[i ^ 1].f += flow, used += flow; if (used == low || dist[S] > T) return used; } if (! -- gap[dist[t]]) dist[S] = T + 1; else ++ gap[++ dist[t]], g[t] = h[t]; return used; }
int maxflow() { bfs(); int flow = 0; while (dist[S] <= T) flow += dfs(S, 1e9); return flow; } }
int main() { int q, m; while (scanf("%d%d", &q, &m), q) { nume = 1, memset(h, 0, sizeof h); flow :: S = m << 1, flow :: T = (m << 1) + 1; for (int i = 0; i < q; ++ i) for (int j = 0; j < q; ++ j) scanf("%d", &mp[i][j]); for (int i = 0; i < q; ++ i) for (int j = 0; j < q; ++ j) if (! ~ mp[i][j]) mp[i][j] = 1e9; for (int k = 0; k < q; ++ k) for (int i = 0; i < q; ++ i) for (int j = 0; j < q; ++ j) mp[i][j] = min(mp[i][j], mp[i][k] + mp[k][j]); for (int i = 0; i < m; ++ i) scanf("%d%d%d", &p[i], &t[i], &d[i]), -- p[i]; for (int i = 0; i < m; ++ i) for (int j = 0; j < m; ++ j) if (i != j && t[i] + d[i] + mp[p[i]][p[j]] <= t[j]) add_edge(i, j + m, 1); for (int i = 0; i < m; ++ i) add_edge(flow :: S, i, 1), add_edge(i + m, flow :: T, 1); printf("%d\n", m - flow :: maxflow()); } return 0; }
|