标签:
Description
Input
Output
Sample Input
Sample Output
#include<stdio.h>
#include<string.h>
#include<math.h>
#include<queue>
#include<vector>
#include<algorithm>
using namespace std;
const int maxn = 3100;
const int INF = 0x3f3f3f3f;
const double eps = 1e-5;
struct Guest{
    double x,y,s;
}guests[maxn];
struct Umbrella{
    double x,y;
}umbrellas[maxn];
double distan(Guest a,Umbrella b){
    double dx = a.x - b.x;
    double dy = a.y - b.y;
    return sqrt(dx*dx+dy*dy);
}
vector<int>G[maxn];
int Mx[maxn], My[maxn], dx[maxn], dy[maxn], used[maxn], dis;
bool SearchP(int _n){   //传参x部的顶点个数,处理出来dx与dy数组
    queue<int>Q;
    memset(dx,-1,sizeof(dx));
    memset(dy,-1,sizeof(dy));
    int dis = INF;
    for(int i = 1; i <= _n; i++){
        if(Mx[i] == -1){    //将x部的未盖点入队
            dx[i] = 0;
            Q.push(i);
        }
    }
    int v;
    while(!Q.empty()){
        int u = Q.front(); Q.pop();
        if(dx[u] > dis) break;  //没有更小的dis
        for(int i = 0; i < G[u].size(); i++){
            v = G[u][i];
            if(dy[v] == -1){        //如果y部的v没有访问过
                dy[v] = dx[u] + 1;  //更新dy
                if(My[v] == -1){    //如果y部的v是未盖点,找到了最短增广路长度
                    dis = dy[v];
                }else{
                    dx[My[v]] = dy[v] + 1;  //更新v的x部匹配点
                    Q.push(My[v]);          //将v的匹配点入队
                }
            }
        }
    }
    return dis != INF;                      //找到了最短增广路
}
int dfs(int u){
    int v;
    for(int i = 0; i < G[u].size(); i++){
        v = G[u][i];
        if(!used[v] && dy[v] == dx[u] + 1){ //v未访问过且距离相差为1
            used[v] = 1;
            if(My[v] != -1 && dy[v] == dis){    //如果v不是未盖点且已经等于最短增广路距原点距离,说明有更短的可以去增广
                continue;
            }
            if(My[v] == -1 || dfs(My[v])){  //如果v是y部未盖点或者原来跟v匹配的x部节点能另外找到一个匹配
                Mx[u] = v;                  //匹配u、v
                My[v] = u;
                return true;
            }
        }
    }
    return false;
}
int MaxMatch(int ln,int rn){    //传参左、右部顶点个数,返回最大匹配个数
    int ret = 0;
    memset(Mx,-1,sizeof(Mx));   //x部初始化未盖点
    memset(My,-1,sizeof(My));   //y部初始化未盖点
    while(SearchP(ln)){
        memset(used,0,sizeof(used));    //初始化未访问
        for(int i = 1; i <= ln; i++){
            if(Mx[i] == -1 && dfs(i)){  //如果x部为未盖点且找到了增广路
                ret++;
            }
        }
    }
    return ret;
}
int main(){
    int T, cas = 0, n, m;
    double t;
    scanf("%d",&T);
    while(T--){
        scanf("%lf",&t);
        scanf("%d",&m);
        for(int i = 0; i <= m; i++){
            G[i].clear();
        }
        for(int i = 1; i <= m; i++){
            scanf("%lf%lf%lf",&guests[i].x,&guests[i].y,&guests[i].s);
        }
        scanf("%d",&n);
        for(int i = 1; i <= n; i++){
            scanf("%lf%lf",&umbrellas[i].x,&umbrellas[i].y);
        }
        for(int i = 1; i <= m; i++){
            for(int j = 1; j <= n; j++){
                double dd = distan(guests[i],umbrellas[j]);
                if(guests[i].s * t >= dd){
                    G[i].push_back(j);
                }
            }
        }
        int res = MaxMatch(m,n);
        printf("Scenario #%d:\n%d\n\n",++cas,res);
    }
    return 0;
}
HDU 2389 ——Rain on your Parade——————【Hopcroft-Karp求最大匹配、sqrt(n)*e复杂度】
标签:
原文地址:http://www.cnblogs.com/chengsheng/p/4955426.html