HDU_1960
If you think of each route as a point, and then after task I is completed, you can rush to the task j and even a directed edge of I-> j, in this way, we get a directed acyclic graph, and the question is equivalent to covering all the vertices with the least path, which converts the problem to the minimum path overwrite problem of the Bipartite Graph.
#include<stdio.h>#include<string.h>#include<stdlib.h>#define MAXD 510#define MAXM 250010char b[10];int N, first[MAXD], e, next[MAXM], v[MAXM];int yM[MAXD], visy[MAXD];struct Task{ int t, x1, y1, x2, y2; }task[MAXD];int can(int i, int j){ return task[i].t + abs(task[j]. x1 - task[i].x2) + abs(task[j].y1 - task[i].y2) + abs(task[i].x2 - task[i].x1) + abs(task[i].y2 - task[i].y1) < task[j].t;}void add(int x, int y){ v[e] = y; next[e] = first[x], first[x] = e ++; }void init(){ int i, j, hh, mm; scanf("%d", &N); for(i = 0; i < N; i ++) { scanf("%s%d%d%d%d", b, &task[i].x1, &task[i].y1, &task[i].x2, &task[i].y2); sscanf(b, "%d:%d", &hh, &mm); task[i].t = hh * 60 + mm; } memset(first, -1, sizeof(first[0]) * N), e = 0; for(i = 0; i < N; i ++) for(j = 0; j < N; j ++) if(can(i, j)) add(i, j);}int searchpath(int cur){ int i; for(i = first[cur]; i != -1; i = next[i]) if(!visy[v[i]]) { visy[v[i]] = 1; if(yM[v[i]] == -1 || searchpath(yM[v[i]])) { yM[v[i]] = cur; return 1; } } return 0;}void solve(){ int i, ans = 0; memset(yM, -1, sizeof(yM[0]) * N); for(i = 0; i < N; i ++) { memset(visy, 0, sizeof(visy[0]) * N); if(searchpath(i)) ++ ans; } printf("%d\n", N - ans);}int main(){ int t; scanf("%d", &t); while(t --) { init(); solve(); } return 0; }