这道题目,点数比较多,用匈牙利算法会超时!
题目很简答,现在发现二分匹配建图很重要。这道题就是把人和人能在t时间内可以拿到的雨伞连起来即可,一左一右。
很傻的错误就是在最后输出的时候,printf函数里面应该是表示数据组号的地方的%d我直接写成1,导致最后结果会变成1 2 3……所以以后写代码还是要注意格式,注意格式的逻辑性和保证思维的清晰度!
代码如下:
#include <cstdio>
#include <cstring>
#include <queue>
#include <algorithm>
using namespace std;
const int N = 3030;
const int INF = 0x3fffffff;
int T, t, ges, umb, bimap[N][N];
struct posg{
int x, y, s;
}G[N];
struct posb{
int x, y;
}B[N];
int cy[N], cx[N];
int dx[N], dy[N], dis;
bool used[N];
bool search()
{
queue<int> Q;
dis = INF;
memset( dx, -1, sizeof(dx));
memset( dy, -1, sizeof(dy));
for ( int i = 1; i <= ges; ++i )
if ( cx[i] == -1 ) {
Q.push(i);
dx[i] = 0;
}
while ( !Q.empty() ) {
int u = Q.front();
Q.pop();
if ( dx[u] > dis ) break;
for ( int v = 1; v <= umb; ++v )
if ( bimap[u][v] && dy[v] == -1 ) {
dy[v] = dx[u] + 1;
if ( cy[v] == -1 ) dis = dy[v];
else {
dx[cy[v]] = dy[v]+1;
Q.push( cy[v] );
}
}
}
return dis!=INF;
}
bool dfs( int u )
{
for ( int v = 1; v <= umb; ++v ) if ( bimap[u][v] && !used[v] && dx[u] + 1 == dy[v] ) {
used[v] = 1;
if ( cy[v] != -1 && dy[v] == dis ) continue;
if ( cy[v] == -1 || dfs( cy[v] ) ) {
//printf("%d %d\n", u, v);
cy[v] = u;
cx[u] = v;
return 1;
}
}
return 0;
}
int Hmatch()
{
int res = 0;
memset( cy, -1, sizeof(cy));
memset( cx, -1, sizeof(cx));
while ( search() ) {
memset( used, 0, sizeof(used));
for ( int i = 1; i <= ges; ++i ) if ( cx[i] == -1 ) {
res += dfs(i);
}
}
return res;
}
int getdis( int i, int j ) {
return ( G[i].x-B[j].x )*( G[i].x-B[j].x ) + ( G[i].y-B[j].y )*( G[i].y-B[j].y );
}
int main()
{
int icase = 1;
scanf("%d", &T);
while ( T-- ) {
scanf("%d%d", &t, &ges);
for ( int i = 1; i <= ges; ++i ) scanf("%d%d%d", &G[i].x, &G[i].y, &G[i].s);
scanf("%d", &umb);
for ( int i = 1; i <= umb; ++i ) scanf("%d%d", &B[i].x, &B[i].y);
memset( bimap, 0, sizeof(bimap));
for ( int i = 1; i <= ges; ++i )
for ( int j = 1; j <= umb; ++j )
if ( (t*G[i].s)*(t*G[i].s) >= getdis(i, j) ) bimap[i][j] = 1;
//for ( int i = 1; i <= ges; ++i, printf("\n") ) for ( int j = 1; j <= umb; ++j ) printf(" %d", bimap[i][j]);
printf("Scenario #%d:\n", icase++);
printf("%d\n\n", Hmatch());
//for ( int i = 1; i <= ges; ++i ) printf("%d\n", cy[i]);
}
}