SPOJ4206Fast Maximum Matching(hopcroft-karp)

题目请戳这里

题目大意:裸的二分匹配。

题目分析:数据比较强,用来测模版的。这题用hungry跑着会比较吃力,所以用hopcroft-karp算法。这个算法较hungry高效是因为每次bfs找到一个增广路集,然后用dfs进行多路增广,同时找多条增广路,从而效率大增。其实怎么看hk算法都是个没有边权的dinic啊。

参照着wikipedia 敲了一个hk,效率貌似不高啊。。。

详情请见代码:

 

#include <iostream>

#include<cstdio>

#include<cstring>

using namespace std;

const int N = 50001;

const int M = 150001;

const int inf = 0x3f3f3f3f;



int head[N];

struct node

{

    int to,next;

}g[M];

int m,n,p,num;

int matchx[N],matchy[N],que[N],dis[N];

void build(int s,int e)

{

    g[num].to = e;

    g[num].next = head[s];

    head[s] = num ++;

}

bool bfs()

{

    int i,j;

    int front,rear;

    front = rear = 0;

    for(i = 1;i <= n;i ++)

    {

        if(!matchx[i])

        {

            dis[i] = 0;

            que[rear ++] = i;

        }

        else

            dis[i] = inf;

    }

    dis[0] = inf;

    while(front != rear)

    {

        int u = que[front ++];

        if(front == N)

            front = 0;

        for(i = head[u];~i;i = g[i].next)

        {

            int v = g[i].to;

            if(dis[matchy[v]] == inf)

            {

                dis[matchy[v]] = dis[u] + 1;

                que[rear ++] = matchy[v];

                if(rear == N)

                    rear = 0;

            }

        }

    }

    return dis[0] != inf;

}

bool dfs(int u)

{

    int i,v;

    for(i = head[u];~i;i = g[i].next)

    {

        v = g[i].to;

        if(dis[matchy[v]] == dis[u] + 1)

            if(matchy[v] == 0 || dfs(matchy[v]))

            {

                matchx[u] = v;

                matchy[v] = u;

                return true;

            }

    }

    dis[u] = inf;

    return false;

}



void Hopcroft_Karp()

{

    memset(matchx,0,sizeof(matchx));

    memset(matchy,0,sizeof(matchy));

    int ans = 0;

    while(bfs())

    {

        for(int i = 1;i <= n;i ++)

            if(!matchx[i])

                if(dfs(i))

                    ans ++;

    }

    printf("%d\n",ans);

}

int main()

{

    int a,b;

    while(scanf("%d",&n) != EOF)

    {

        memset(head,-1,sizeof(head));

        num = 1;

        scanf("%d%d",&m,&p);

        while(p --)

        {

            scanf("%d%d",&a,&b);

            build(a,b);

        }

        Hopcroft_Karp();

    }

    return 0;

}


 

 

你可能感兴趣的:(match)