#include<bits/stdc++.h>
using namespace std;
int n,m;
int INF=0x3f3f3f;
int dis;
int cx[3003];
int dy[3002];
int cy[3003];
int dx[3003];
int used[3002];
int a[3003];
int b[3002];
int c[3002];
int d[3002];
int e[3002];
int mp[3002][3002];
bool searchpath()
{
queue<int>Q;
dis=INF;
memset(dx,-1,sizeof(dx));
memset(dy,-1,sizeof(dy));
for(int i=0; i<m; i++)
{
if(cx[i]==-1)
{
Q.push(i);
dx[0]=1;
}
}
while(!Q.empty())
{
int u=Q.front();
Q.pop();
if(dx[u]>dis)
break;
for(int i=0; i<n; i++)
{
if(mp[u][i]&&dy[i]==-1)
{
dy[i]=dx[u]+1;
if(cy[i]==-1)
{
dis=dy[i];
}
else
{
dx[cy[i]]=dy[i]+1;
Q.push(cy[i]);
}
}
}
}
return dis!=INF;
}
int findpath(int u)
{
for(int i=0;i<n;i++)
{
if(!used[i]&&mp[u][i]&&dy[i]==dx[u]+1){
used[i]=1;
if(dis==dy[i]&&cy[i]!=-1){
continue;
}
else if(cy[i]==-1||findpath(cy[i])){
cy[i]=u;
cx[u]=i;
return 1;
}
}
}
return 0;
}
int maxmatch(){
int res=0;
memset(cx,-1,sizeof(cx));
memset(cy,-1,sizeof(cy));
while(searchpath()){
memset(used,0,sizeof(used));
for(int i=0;i<m;i++){
if(cx[i]==-1)
{
res+=findpath(i);
}
}
}
return res;
}
int main()
{
int t;
cin>>t;
int k;
for(k=1; k<=t; k++)
{
int rain;
scanf("%d",&rain);
memset(mp,0,sizeof(mp));
scanf("%d",&m);
int i,j;
for(i=0; i<m; i++)
{
scanf("%d%d%d",&a[i],&b[i],&c[i]);
}
scanf("%d",&n);
for(i=0; i<n; i++)
{
scanf("%d%d",&d[i],&e[i]);
for(j=0; j<m; j++)
{
if((d[i]-a[j])*(d[i]-a[j])+(e[i]-b[j])*(e[i]-b[j])<=(c[j]*rain)*(c[j]*rain))
mp[j][i]=1;
}
}
int ans=0;
ans=maxmatch();
if(k!=1)
printf("\n");
printf("Scenario #%d:\n",k);
printf("%d\n",ans);
}
}
----HDU 2389测试和hp算法时间复杂都差不多
主要函数部分
這裡介紹一個加速的手段:一開始就把一些明顯可以配對的點給配對起來,這樣就不必替每一個未匹配點建立交錯樹了。這個手段在圖很龐大的時候可以發揮作用。
- int greedy_matching()
- {
- int c = 0;
- for (int x=0; x<nx; ++x)
- if (mx[x] == -1)
- for (int y=0; y<ny; ++y)
- if (my[y] == -1)
- if (adj[x][y])
- {
- mx[x] = y; my[y] = x;
- c++;
- break;
- }
- return c;
- }
- int bipartite_matching()
- {
- memset(mx, -1, sizeof(mx));
- memset(my, -1, sizeof(my));
- int c = greedy_matching(); // 能連的先連一連
- for (int x=0; x<nx; ++x)
- if (mx[x] == -1) // 這行記得補上來
- {
- memset(vy, false, sizeof(vy));
- if (DFS(i)) c++;
- }
- return c;
- }
它的時間複雜度僅為一次 Graph Traversal 的時間,不太會影響原演算法的運行效率。