題意
在開一個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 100000007using 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;}