2 1 2 1 0 3 3 0 3 2 4 0 6 0 1 2 1 1 2 3 3 2 2 2 2 4 4
Scenario #1: 2 Scenario #2: 2
#include<stdio.h>
#include<string.h>
#include<queue>
#include<math.h>
using namespace std;
const int N = 3005;
const int INF=1<<28;
int head[N],to[N*N],next1[N*N],tot;  //存图
int dx[N],dy[N],dis;                 //左边部分距离,右边部分距离,记录右边部分没有被匹配过的点的最大距离
int machx[N],nx,machy[N];            //左边部分点匹配右边点,左边部分的点个数,右边部分点匹配左边的点
bool vist[N];
void addEdg(int u,int v){
    to[tot]=v; next1[tot]=head[u]; head[u]=tot++;
}
bool searchpath(){//找有没有增广路
    queue<int>q;
    dis=INF;
    memset(dx,-1,sizeof(dx));
    memset(dy,-1,sizeof(dy));
    for(int i=1; i<=nx; i++)
        if(machx[i]==-1)
        q.push(i),dx[i]=0;
    while(!q.empty()){
        int u=q.front(); q.pop();
        if(dx[u]>dis)
            break;
        for(int i=head[u]; i!=-1; i=next1[i]){
            int v=to[i];
            if(dy[v]==-1){
                dy[v]=dx[u]+1;
                if(machy[v]==-1)
                    dis=dy[v];
                else{
                    dx[machy[v]]=dy[v]+1;
                    q.push(machy[v]);
                }
            }
        }
    }
    return dis!=INF;
}
bool findroad(int u){
    for(int i=head[u]; i!=-1; i=next1[i]){
        int v=to[i];
        if(!vist[v]&&dy[v]==dx[u]+1){
            vist[v]=1;
            if(machy[v]!=-1&&dy[v]==dis)
                continue;
            if(machy[v]==-1||findroad(machy[v])){
                machy[v]=u; machx[u]=v;  return true;
            }
        }
    }
    return false;
}
int MaxMatch(){
    int ans=0;
    memset(machx,-1,sizeof(machx));
    memset(machy,-1,sizeof(machy));
    while( searchpath() ){
        memset(vist,0,sizeof(vist));
        for(int i=1; i<=nx; i++)
            if(machx[i]==-1)
            ans+=findroad(i);
    }
    return ans;
}
//-------------上面部分的代码为模板---------------------
struct node{
    int x,y;
    double dis;
}man[N],umb[N];
double countDis(int u,int v){
    return sqrt((man[u].x-umb[v].x)*(man[u].x-umb[v].x)*1.0+(man[u].y-umb[v].y)*(man[u].y-umb[v].y)*1.0);
}
int main(){
    int T,ny,tim,c=0;
    scanf("%d",&T);
    while(T--){
        scanf("%d%d",&tim,&nx);
        for(int i=1;i<=nx;i++){
            scanf("%d%d%lf",&man[i].x,&man[i].y,&man[i].dis);
            man[i].dis*=tim;
        }
        scanf("%d",&ny);
        for(int i=1;i<=ny;i++)
            scanf("%d%d",&umb[i].x,&umb[i].y);
//---------------------建图---------------------
        tot=0;
        memset(head,-1,sizeof(head));
        for(int u=1;u<=nx;u++)
            for(int v=1;v<=ny;v++)
            if(man[u].dis>=countDis(u,v))
                addEdg(u,v);
//----------------------------------------------
        int ans=MaxMatch();
        printf("Scenario #%d:\n%d\n\n",++c,ans);
    }
    return 0;
}
HDU 2389 Rain on your Parade (二分图匹配(Hopcroft-Carp的算法模板))
原文地址:http://blog.csdn.net/u010372095/article/details/45772801