有很多出租車訂單,標記了開車時間與起點終點。
如果出租車能在上一個訂單結束後,並且在下一個訂單的開車前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;}