HDU2389Rain on your Parade(最大匹配+Hopcroft-Karp算法)

来源:互联网 发布:淘宝设计工作室 编辑:程序博客网 时间:2024/06/06 02:45

原图地址:点击打开链接

该题即使简单的二分图最大匹配问题,用匈牙利算法O(n*m)会超时,所以这里我们用Hopcroft-Karp算法,这个算法的时间复杂度为O(sqrt(n)*m).如果不了解这个算法可以看另一篇博客点击打开链接


#include<stdio.h>#include<string.h>#include<queue>#include<vector>#include<math.h>#define INF 1<<31-1using namespace std; struct Position{int x;int y;double speed;}peo[3010],umb[3010];vector<int>edge[3010];bool used[3010];int fx[3010];int fy[3010];int dx[3010];int dy[3010];int len;int m,n,k=0;bool judge(Position p1,Position p2,int time){double d=sqrt((p1.x-p2.x)*(p1.x-p2.x)+(p1.y-p2.y)*(p1.y-p2.y));if(p1.speed*time>=d)return true;return false;}bool searchPath()         //找寻最短的增广路径 {int i;queue<int>Q;len=INF;memset(dx,-1,sizeof(dx));memset(dy,-1,sizeof(dy));for(i=1;i<=m;i++){if(fx[i]==-1){Q.push(i);dx[i]=0;}}while(!Q.empty()){int u=Q.front();Q.pop();if(dx[u]>len)break;for(i=0;i<edge[u].size();i++){int v=edge[u][i];if(dy[v]==-1){dy[v]=dx[u]+1;if(fy[v]==-1)len=dy[v];else{dx[fy[v]]=dy[v]+1;Q.push(fy[v]);}}}}if(len!=INF)return true;return false;}bool find(int u){int i;for(i=0;i<edge[u].size();i++){int v=edge[u][i];if(!used[v]&&dy[v]==dx[u]+1){used[v]=true;if(fy[v]!=-1&&dy[v]==len)continue;if(fy[v]==-1||find(fy[v])){fy[v]=u;fx[u]=v;return true;}}}return false;}int solve(){int i,res=0;memset(fy,-1,sizeof(fy));memset(fx,-1,sizeof(fx));while(searchPath()){memset(used,0,sizeof(used));for(i=1;i<=m;i++){if(fx[i]==-1&&find(i))res++;}}return res;}int main(){int i,j,t,time;scanf("%d",&t);while(t--){scanf("%d",&time);scanf("%d",&m);for(i=1;i<=m;i++)   scanf("%d%d%lf",&peo[i].x,&peo[i].y,&peo[i].speed);scanf("%d",&n);for(i=1;i<=n;i++)   scanf("%d%d",&umb[i].x,&umb[i].y);   for(i=1;i<=m;i++){edge[i].clear();for(j=1;j<=n;j++){if(judge(peo[i],umb[j],time)){edge[i].push_back(j);}}}int res=solve();printf("Scenario #%d:\n%d\n\n",++k,res);}}




0 0
原创粉丝点击