//m个任务,每个任务都有开始时间和需要花的时间,以及其在哪楼地方工作
//给出地图,每楼到另一楼的路径所花的时间
//问最少需要安排多少人能完成这些任务
//对任务和任务之间建图,如果做完任务i还能做任务j那么i-j之间建立一条边
//这样只需要找到最小路径覆盖即为最终答案
#include<cstdio>
#include<iostream>
#include<cstring>
using namespace std ;
const int maxn = 210 ;
const int inf = 0x3f3f3f3f ;
int map[maxn][maxn] ;
int vis[maxn] ;
int match[maxn];
int dis[maxn][maxn] ;
struct node
{
int st , id , ti ;
}t[maxn] ;
int n , m;
void floyd()
{
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][k] + dis[k][j] , dis[i][j]) ;
}
bool find(int st)
{
for(int i = 1;i <= m;i++){
if(!vis[i] && map[st][i]){
vis[i] = 1 ;
if(match[i] == -1 || find(match[i])){
match[i] = st ;
return true ;
}
}
}
return false ;
}
int main()
{
while(scanf("%d%d" , &n , &m) && (n+m))
{
memset(match , -1 , sizeof(match)) ;
memset(map , 0 , sizeof(map)) ;
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 ;
}
floyd() ;
for(int i = 1;i <= m;i++)
scanf("%d%d%d" , &t[i].id , &t[i].st , &t[i].ti) ;
for(int i = 1;i <= m;i++){
for(int j = 1;j <= m;j++){
if(i == j) continue ;
if(t[i].st + t[i].ti + dis[t[i].id][t[j].id] <= t[j].st)
map[i][j] = 1 ;
}
}
int ans = 0 ;
for(int i = 1;i <= m;i++){
memset(vis , 0 , sizeof(vis)) ;
if(find(i))
ans++ ;
}
cout<<m-ans<<endl;
}
return 0 ;
}
版权声明:本文为博主原创文章,未经博主允许不得转载。
poj3216Repairing Company 二分匹配之最小路径覆盖+floyd
原文地址:http://blog.csdn.net/cq_pf/article/details/47313431