POJ 2060 最小路径覆盖

来源:互联网 发布:英语6级口语考试知乎 编辑:程序博客网 时间:2024/06/03 15:23

有很多出租车订单,标记了开车时间与起点终点。

如果出租车能在上一个订单结束后,并且在下一个订单的开车前1min到达起点,那么我们说,这两个订单可以用一辆出租车来完成任务。

转化为最小路径覆盖问题。

这里是有向图的最大匹配,可以用匈牙利算法求解。

以上....

#include<iostream>#include<cstdio>using namespace std;struct SEG{    int s,e,a,b,c,d;}t[555];struct Edge{    int v,next;}E[555555];bool judge( SEG a,SEG b ){  if( a.e+abs(a.c-b.a)+abs(a.d-b.b)<b.s )   return true;  return false;}bool vis[555];int match[555],ptr[555];int Edgenum;void addEdge( int u,int v ){  E[Edgenum].v=v;  E[Edgenum].next=ptr[u];  ptr[u]=Edgenum++;}bool Match( int cur ){  for( int i=ptr[cur];i!=-1;i=E[i].next )  {    if( !vis[E[i].v] )    {     vis[E[i].v]=true;     if( match[E[i].v]==-1 || Match(match[E[i].v]) )     {     match[E[i].v]=cur;     return true;  }    } }  return false;}int main(){ //freopen( "test.in","r",stdin ); //freopen( "test.out","w",stdout ); int T; scanf( "%d",&T ); while( T-- ) {    memset( ptr,-1,sizeof(ptr) );    memset( match,-1,sizeof(match) );    Edgenum=0;    int N;    scanf( "%d",&N );    int h,m,a,b,c,d;    for( int i=0;i<N;i++ )    {    scanf( "%d:%d %d %d %d %d",&h,&m,&a,&b,&c,&d );    t[i].s=h*60+m;    t[i].e=t[i].s+abs(a-c)+abs(b-d);    t[i].a=a;t[i].b=b;t[i].c=c;t[i].d=d;   }   for( int i=0;i<N;i++ )   for( int j=0;j<N;j++ )   {   if( judge(t[i],t[j]) )   addEdge(i,j);      }      int ans=0;      for( int i=0;i<N;i++ )      {   memset( vis,0,sizeof(vis) );   if( Match(i) )   ans++;   }   printf( "%d\n",N-ans );  } return 0;}


原创粉丝点击