标签:
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