题意
在开一个Party...被告知t分钟后会下雨...告诉每个人的坐标以及其跑步的速度..告诉每把伞的坐标..问最多能让多少个人躲雨成功...
题解:
根据距离速度的关系构边.....然后跑二分图最大匹配匈牙利会超时...第一次发现还有个Hopcroft-Carp的方法...直接拿来当模板了...
Program:
#include<iostream> #include<stdio.h> #include<algorithm> #include<cmath> #include<stack> #include<string.h> #include<queue> #define ll long long #define esp 1e-5 #define MAXN 3005 #define MAXM 50000005 #define oo 100000007 using namespace std; struct node { int x,y,sp; bool operator <(node a) const { return x<a.x; } }P[MAXN],U[MAXN]; int n,match[MAXN]; bool g[MAXN][MAXN],used[MAXN]; int Mx[MAXN],My[MAXN],Nx,Ny; int dx[MAXN],dy[MAXN],dis; bool vst[MAXN]; //------------Hopcroft-Carp模板-----g[][]存图,记得初始化Nx,Ny--------- bool searchP() { queue<int>Q; dis=oo; memset(dx,-1,sizeof(dx)); memset(dy,-1,sizeof(dy)); for(int i=1;i<=Nx;i++) if(Mx[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<=Ny;v++) if(g[u][v]&&dy[v]==-1) { dy[v]=dx[u]+1; if(My[v]==-1) dis=dy[v]; else { dx[My[v]]=dy[v]+1; Q.push(My[v]); } } } return dis!=oo; } bool DFS(int u) { for(int v=1;v<=Ny;v++) if(!vst[v]&&g[u][v]&&dy[v]==dx[u]+1) { vst[v]=1; if(My[v]!=-1&&dy[v]==dis) continue; if(My[v]==-1||DFS(My[v])) { My[v]=u; Mx[u]=v; return 1; } } return 0; } int MaxMatch() { int res=0; memset(Mx,-1,sizeof(Mx)); memset(My,-1,sizeof(My)); while(searchP()) { memset(vst,0,sizeof(vst)); for(int i=1;i<=Nx;i++) if(Mx[i]==-1&&DFS(i)) res++; } return res; } //-------------Hopcroft-Carp------------------ bool ok(int a,int b,int t) { int dis=(P[a].x-U[b].x)*(P[a].x-U[b].x)+(P[a].y-U[b].y)*(P[a].y-U[b].y); return dis<=(t*P[a].sp)*(t*P[a].sp); } int main() { int T,m,i,j,t,cases; freopen("input.txt","r",stdin); freopen("output.txt","w",stdout); scanf("%d",&T); for (cases=1;cases<=T;cases++) { scanf("%d%d",&t,&n); for (i=1;i<=n;i++) scanf("%d%d%d",&P[i].x,&P[i].y,&P[i].sp); scanf("%d",&m); for (i=1;i<=m;i++) scanf("%d%d",&U[i].x,&U[i].y); sort(P+1,P+1+n),sort(U+1,U+1+n); memset(g,0,sizeof(g)); for (i=1;i<=n;i++) for (j=1;j<=m;j++) if (ok(i,j,t)) g[i][j]=true; Nx=n,Ny=m; printf("Scenario #%d:\n%d\n\n",cases,MaxMatch()); } return 0; }