Description
Lily runs a repairing company that services the Q blocks in the city. One day the company receives M repair tasks, the ith of which occurs in block pi, has a deadline ti on any repairman’s arrival, which is also its starting time, and takes a single repairman di time to finish. Repairmen work alone on all tasks and must finish one task before moving on to another. With a map of the city in hand, Lily want to know the minimum number of repairmen that have to be assign to this day’s tasks.
Input
The input contains multiple test cases. Each test case begins with a line containing Q and M (0 < Q ≤ 20, 0 < M ≤ 200). Then follow Q lines each with Q integers, which represent a Q × Q matrix Δ = {δij}, where δij means a bidirectional road connects the ith and the jth blocks and requires δij time to go from one end to another. If δij = −1, such a road does not exist. The matrix is symmetric and all its diagonal elements are zeroes. Right below the matrix are M lines describing the repairing tasks. The ith of these lines contains pi, ti and di. Two zeroes on a separate line come after the last test case.
Output
For each test case output one line containing the minimum number of repairmen that have to be assigned.
Sample Input
1 2 0 1 1 10 1 5 10 0 0
Sample Output
2
#include <iostream> #include <cstdio> #include <cstring> using namespace std; #define maxn 280 #define edge maxn*maxn #define inf 0x3f3f3f3f bool vis[maxn]; int q,m,e; int marry[maxn],dis[maxn][maxn]; int first[maxn]; int vv[edge],nxt[edge]; struct RW { int p,t,d; }rw[maxn]; inline int min(int a,int b) { return a>b?b:a; } void addEdge(int u,int v) { vv[e] = v; nxt[e] = first[u]; first[u] = e++; } void floyd() { for(int i = 1;i <= q;i++) { for(int j = 1;j <= q;j++) { for(int k = 1;k <= q;k++) { if(j != k) dis[j][k] = min(dis[j][k],dis[j][i] + dis[i][k]); } } } } void createmap() { for(int i = 1;i <= m;i++) { for(int j = 1;j <= m;j++) { if(i == j) continue; if(dis[rw[i].p][rw[j].p] != inf && rw[i].t + rw[i].d + dis[rw[i].p][rw[j].p] <= rw[j].t) addEdge(i,j); } } } bool dfs(int u) { //vis[u] = 1;这句是不能+的。想想为什么。 for(int i = first[u];i != -1;i = nxt[i]) { int v = vv[i]; if(!vis[v]) { vis[v] = 1; if(!marry[v] || dfs(marry[v]))//你能不能找别的儿子,这个儿子给我。这里的DFS就是上面vis[u]=1不能+的原因、。沿V找不到未覆盖点不代表沿marry[v]找不到覆盖点。 { marry[v] = u; return 1; } } } return 0; } int main() { //freopen("in.txt","r",stdin); while(scanf("%d%d",&q,&m)==2 && (q||m)) { memset(dis,0x3f,sizeof(dis)); memset(first,-1,sizeof(first)); memset(marry,0,sizeof(marry)); e = 0; for(int i = 1;i <= q;i++) { for(int j = 1;j <= q;j++) { int d;scanf("%d",&d); if(d != -1) dis[i][j] = d; } } for(int i = 1;i <= m;i++) { scanf("%d%d%d",&rw[i].p,&rw[i].t,&rw[i].d); } floyd(); createmap(); int ans = 0; for(int i = 1;i <= m;i++) { memset(vis,0,sizeof(vis)); vis[i] = 1; if(dfs(i)) ans++; } printf("%d\n",m-ans); } return 0; }
本文介绍了一个城市维修任务分配问题,通过构建图模型并运用Floyd算法和匈牙利算法来求解最小维修人员数量。该问题涉及到图论、最短路径算法及匹配算法等计算机科学领域的知识。
976

被折叠的 条评论
为什么被折叠?



