题意:出租车公司有n个预约, 每个预约有时间和地点, 地点分布在二维整数坐标系上, 地点之间的行驶时间为两点间的曼哈顿距离(|x1 - x2| + |y1 - y2|)。一辆车可以在运完一个乘客后运另一个乘客, 条件是此车要在预约开始前一分钟之前到达出发地, 问最少需要几辆车搞定所有预约。
这里用到的知识是 最小路径覆盖 = 总节点数 – 最大独立集数(最大匹配数);
这里建图要注意的是如果这个地方没预约,我们可以从这个地方开到有预约的地方去;所以这个地方要发费时间;
#include<iostream> #include<cstdio> #include<cstdlib> #include<algorithm> #include<cmath> #include<queue> #include<set> #include<map> #include<cstring> #include<vector> using namespace std; class Node { public: int start,end; int a,b,c,d; }; bool G[524][524],visit[524]; int match[524]; bool cmp( Node a , Node b ) { return a.start < b.start; } bool path( int num , int N ) { for( int i = 1 ; i <= N ; i ++ ) { if( !visit[i] && G[num][i] ) { visit[i] = true; if( !match[i] || path( match[i], N ) ) { match[i] = num; return true; } } } return false; } int main( ) { int hour,minute,a,b,c,d,N,n; Node node[524]; while( scanf( "%d",&N )==1 ) { while( N-- ) { scanf( "%d",&n ); memset( G, 0 , sizeof( G ) ); memset( match , 0 , sizeof( match ) ); for( int i = 1; i <= n ; i++ ) { scanf( "%d:%d %d %d %d %d",&hour,&minute,&node[i].a,&node[i].b,&node[i].c,&node[i].d ); int t = hour * 60 + minute ; int tt = abs( node[i].a - node[i].c ) + abs( node[i].b -node[i].d ); node[i].start = t ; node[i].end = node[i].start + tt; } sort( node + 1 , node + n + 1 , cmp ); for( int i = 1 ; i <= n ; i ++ ) { for( int j = i+1 ; j <= n ; j ++ ) { int t = abs(node[i].c-node[j].a) + abs(node[i].d - node[j].b) ; if( node[i].end + t < node[j].start ) G[i][j] = true; } } int ans = 0 ; for( int i = 1 ; i <= n ; i ++ ) { memset( visit , 0 , sizeof( visit ) ); if( path( i , n ) ) ans ++; } printf( "%d\n", n - ans ); } } //system( "pause" ); return 0; }