0
点赞
收藏
分享

微信扫一扫

POJ2060最小路径覆盖

题意:
      有n个任务,如果时间来得及干完某些任务后还可以接着干别的任务,给一个任务清单,问最少派出去多少人能完成所有任务。


思路: 
      比较简单的追小路径覆盖问题了,在DAG中找到最少的简单路径去覆盖所有点,结论等于n-最大匹配数,可以这样理解,最开始没有边任务都需要一个人,共n个,然后只要有一条边(干完A活来的及干B活那么连边AB),就有可能减少一个人,当A-B A-C这样的时候只能节省其中的一条,匹配也是,只能把A匹配给一个,这样说是不是很容易理解为什么最小路径覆盖的结论是n-最大匹配数了吧。

#include<stdio.h>

#include<string.h>



#define N_node 500 + 10

#define N_edge 500 * 500 + 100



typedef struct

{

int time ,t,x1 ,x2 ,y1 ,y2;

}NODE;



typedef struct

{

int to ,next;

}STAR;



NODE node[N_node];

STAR E[N_edge];

int list[N_node] ,tot;

int mkgx[N_node] ,mkdfs[N_node];



void add(int a ,int b)

{

E[++tot].to = b;

E[tot].next = list[a];

list[a] = tot;

}



int DFS_XYL(int x)

{

for(int k = list[x] ;k ;k = E[k].next)

{

int to = E[k].to;

if(mkdfs[to]) continue;

mkdfs[to] = 1;

if(mkgx[to] == -1 || DFS_XYL(mkgx[to]))

{

mkgx[to] = x;

return 1;

}

}

return 0;

}



int abss(int x)

{

return x < 0 ? -x : x;

}



bool ok(int a ,int b)

{

int t1 = abss(node[a].x1 - node[a].x2) + abss(node[a].y1 - node[a].y2);

int t2 = abss(node[a].x2 - node[b].x1) + abss(node[a].y2 - node[b].y1);

return node[b].t - node[a].t > t1 + t2;

}



int main ()

{

int t ,n ,i ,j ,a ,b;

scanf("%d" ,&t);

while(t--)

{

scanf("%d" ,&n);

int tmp = 0;

for(i = 1 ;i <= n ;i ++)

{

scanf("%d:%d %d %d %d %d" ,&a ,&b ,&node[i].x1 ,&node[i].y1 ,&node[i].x2 ,&node[i].y2);

node[i].time = a * 60 + b;

if(i != 1 && node[i].time < node[i-1].time)

tmp ++;

node[i].t = node[i].time + tmp * 24 * 60;

}

memset(list ,0 ,sizeof(list));

tot = 1;

for(i = 1 ;i <= n ;i ++)

for(j = i + 1 ;j <= n ;j ++)

{

if(ok(i ,j)) add(i ,j);

}

memset(mkgx ,255 ,sizeof(mkgx));

int Ans = 0;

for(i = 1 ;i <= n ;i ++)

{

memset(mkdfs ,0 ,sizeof(mkdfs));

Ans += DFS_XYL(i);

}

printf("%d\n" ,n - Ans);

}

return 0;

}



举报

相关推荐

0 条评论