Time Limit: 1000MS | Memory Limit: 131072K | |
Total Submissions: 5867 | Accepted: 1586 |
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 tion 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. Theith 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
Source
有一家修理公司到每户人家修东西,要在t时刻开始修理,修理d小时,从一户人家到另一户人家需要一定的时间,问你最少派多少工人。
首先用floyd算法求解每户人家之间的距离dis[i][j],再把所有任务按开始时间t排序,如果发现tx+dx+dis[x][y]<=ty就在x任务和y任务之间连一条边,表示一个工人修好了x还能继续去修y。这样得到一个DGA,我们就可以对这个图求解一次最小路径覆盖就可以解决问题。
#include<cstdio>
#include<cstring>
#include<algorithm>
#define INF 1<<29
#define maxn 209
using namespace std;
int n,m;
int vis[maxn],cx[maxn],cy[maxn];
bool a[maxn][maxn];
int dis[maxn][maxn];
struct node
{
int p,s,d;
};
struct node task[maxn];
int path(int u)
{
int v;
for(v=0;v<m;v++)
{
if(!vis[v]&&a[u][v])
{
vis[v]=1;
if(cy[v]==-1||path(cy[v]))
{
cy[v]=u;
cx[u]=v;
return 1;
}
}
}
return 0;
}
bool cmp(node x,node y)
{
return x.s<y.s;
}
int match()
{
int res=0;
memset(cx,-1,sizeof(cx));
memset(cy,-1,sizeof(cy));
for(int i=0;i<m;i++)
{
if(cx[i]==-1)
{
memset(vis,0,sizeof(vis));
res+=path(i);
}
}
return res;
}
int main()
{
while(scanf("%d%d",&n,&m),n+m)
{
memset(a,0,sizeof(a));
for(int i=1;i<=n;i++)
for(int j=1;j<=n;j++)
{
scanf("%d",&dis[i][j]);
if(dis[i][j]==-1)
dis[i][j]=INF;
}
for(int k=1;k<=n;k++)
for(int i=1;i<=n;i++)
for(int j=1;j<=n;j++)
dis[i][j]=min(dis[i][j],dis[i][k]+dis[k][j]);
for(int i=0;i<m;i++)
{
scanf("%d%d%d",&task[i].p,&task[i].s,&task[i].d);
}
sort(task,task+m,cmp);
for(int i=0;i<m;i++)
for(int j=i+1;j<m;j++)
{
if(task[i].s+task[i].d+dis[task[i].p][task[j].p]<=task[j].s)
a[i][j]=1;
}
printf("%d\n",m-match());
}
}