hdu2389+二分匹配(Hopcroft-Karp算法)

来源:互联网 发布:淘宝开店2张不同银行卡 编辑:程序博客网 时间:2024/05/17 05:13

题意很简单,显然是对客人与伞做匹配,求最大匹配数。

一开始用了匈牙利,果断TLE。。。

好吧,原来二分匹配还有这个奇葩算法。。然而敲完还是不明白这个算法啥意思。。。

附两个算法的时间复杂度:

匈牙利:O(VE)

H-K :O(V^0.5 E)

#include<cstdio>#include<cstring>#include<vector>#include<queue>using namespace std;int nx,ny,mx[3300],my[3300],dx[3300],dy[3300],vis[3300];vector<int> v[3300];struct node1{    int x,y,sp;}per[3300];struct node2{    int x,y;}umb[3300];bool dfs(int u){    int v2,i;    for(i=0;i<v[u].size();i++)    {        v2=v[u][i];        if(!vis[v2]&&dy[v2]==dx[u]+1)        {            vis[v2]=1;            if(my[v2]==-1||dfs(my[v2]))            {                my[v2]=u;                mx[u]=v2;                return true;            }        }    }    return false;}int hkmatch(){    int ret=0;    memset(mx,-1,sizeof(mx));    memset(my,-1,sizeof(my));    while(true)    {        int i;        bool flag=false;        queue<int> q;        memset(dx,0,sizeof(dx));        memset(dy,0,sizeof(dy));        for(i=1;i<=nx;i++)        {           if(mx[i]==-1)            {                q.push(i);            }        }        while(!q.empty())        {            int z=q.front();            q.pop();            for(i=0;i<v[z].size();i++)            {                int vv=v[z][i];                if(!dy[vv])                {                    dy[vv]=dx[z]+1;                    if(my[vv]==-1) flag=true;                    else                    {                        dx[my[vv]]=dy[vv]+1;                        q.push(my[vv]);                    }                }            }        }        if(flag==false) break;        memset(vis,0,sizeof(vis));        for(i=1;i<=nx;i++)        {            if(mx[i]==-1&&dfs(i))            ret++;        }    }    return ret;}int main(){    int cas,i,j,numcas=0;    scanf("%d",&cas);    while(cas--)    {        int t;        scanf("%d",&t);        scanf("%d",&nx);        for(i=1;i<=nx;i++)            v[i].clear();        for(i=1;i<=nx;i++)            scanf("%d%d%d",&per[i].x,&per[i].y,&per[i].sp);        scanf("%d",&ny);        for(i=1;i<=ny;i++)            scanf("%d%d",&umb[i].x,&umb[i].y);        for(i=1;i<=nx;i++)        {            for(j=1;j<=ny;j++)            {                if(per[i].sp*t*per[i].sp*t>=(per[i].x-umb[j].x)*(per[i].x-umb[j].x)+(per[i].y-umb[j].y)*(per[i].y-umb[j].y))                    v[i].push_back(j);            }        }        printf("Scenario #%d:\n",++numcas);        printf("%d\n\n",hkmatch());    }    return 0;}


0 0
原创粉丝点击