标签:lines lan mbr sea guests more arch anti with
InputThe input starts with a line containing a single integer, the number of test cases.
Each test case starts with a line containing the time t in minutes until it will start to rain (1 <=t <= 5). The next line contains the number of guests m (1 <= m <= 3000), followed by m lines containing x- and y-coordinates as well as the speed si in units per minute (1 <= s i <= 3000) of the guest as integers, separated by spaces. After the guests, a single line contains n (1 <= n <= 3000), the number of umbrellas, followed by n lines containing the integer coordinates of each umbrella, separated by a space.
The absolute value of all coordinates is less than 10000.
OutputFor each test case, write a line containing “Scenario #i:”, where i is the number of the test case starting at 1. Then, write a single line that contains the number of guests that can at most reach an umbrella before it starts to rain. Terminate every test case with a blank line.
Sample Input
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
Sample Output
Scenario #1: 2 Scenario #2: 2
题意:给n个人坐标速度和m个伞坐标进行匹配,转化成二分图匹配
题解:二遍循环判断是否能到达,进行匹配,匈牙利算法会tle,用Hopcroft Karp算法(暂时还不是很理解,先背下来)
参考的博客,图很清楚但是注释有点少http://www.cnblogs.com/penseur/archive/2013/06/16/3138981.html
#include<map> #include<set> #include<cmath> #include<queue> #include<stack> #include<vector> #include<cstdio> #include<cstdlib> #include<cstring> #include<iostream> #include<algorithm> #define pi acos(-1) #define ll long long #define mod 1000000007 using namespace std; const int N=3000+5,maxn=100000+5,inf=0x3f3f3f3f; struct edge{ int x,y,v; }g[N],u[N]; int n,m,dis; bool used[N],ok[N][N]; int mx[N],my[N];//mx保存右侧匹配点,my保存左侧匹配点 int dx[N],dy[N]; double road(edge a,edge b) { return sqrt((a.x-b.x)*(a.x-b.x)+(a.y-b.y)*(a.y-b.y)); } bool searchP()//寻找增广路径集 { queue<int>q; dis=inf; memset(dy,-1,sizeof dy); memset(dx,-1,sizeof dx); for(int i=1;i<=n;i++) if(mx[i]==-1)//将未访问过的左侧点加入队列 { q.push(i); dx[i]=0;//距离设为0 } while(!q.empty()){ int u=q.front(); q.pop(); if(dx[u]>dis)break; for(int i=1;i<=m;i++)//取左侧点匹配到右侧 { if(ok[u][i]&&dy[i]==-1)//右侧点联通且未访问 { dy[i]=dx[u]+1;//i对应距离为u对应距离+1 if(my[i]==-1)dis=dy[i];//i无匹配点 else { dx[my[i]]=dy[i]+1; q.push(my[i]); } } } } return dis!=inf; } bool dfs(int x) { for(int i=1;i<=m;i++) { if(!used[i]&&ok[x][i]&&dy[i]==dx[x]+1)//没有访问过且距上一点为1 { used[i]=1; if(my[i]!=-1&&dy[i]==dis)continue; if(my[i]==-1||dfs(my[i])) { my[i]=x; mx[x]=i; return 1; } } } return 0; } int solve() { int ans=0; memset(mx,-1,sizeof mx); memset(my,-1,sizeof my); while(searchP()){ memset(used,0,sizeof used); for(int i=1;i<=n;i++) if(mx[i]==-1&&dfs(i)) ans++; } return ans; } int main() { ios::sync_with_stdio(false); cin.tie(0); int t,time; cin>>t; for(int k=1;k<=t;k++) { cin>>time>>n; for(int i=1;i<=n;i++)cin>>g[i].x>>g[i].y>>g[i].v; cin>>m; for(int i=1;i<=m;i++)cin>>u[i].x>>u[i].y; for(int i=1;i<=n;i++) { for(int j=1;j<=m;j++) { if(time*g[i].v>=road(g[i],u[j]))ok[i][j]=1; else ok[i][j]=0; } } cout<<"Scenario #"<<k<<":"<<endl<<solve()<<endl<<endl; } return 0; }
标签:lines lan mbr sea guests more arch anti with
原文地址:http://www.cnblogs.com/acjiumeng/p/6740192.html