首页 > 代码库 > 二分图水题三发

二分图水题三发

POJ1274 The Perfect Stall

题目大意:n个奶牛m个仓库,每个奶牛都有喜欢的仓库,当然一个奶牛只能住进一个仓库

 

,一个仓库也只能让一个奶牛吃,问最多有多少奶牛能住进喜欢的仓库

思路:裸的匹配 练下模板

//poj1274

#include <stdio.h>

#include <iostream>

#include<queue>

#include <string.h>

#include <algorithm>

#define maxn 10009

#define maxm 10001

#define esp 0.001

using namespace std;

int head[maxn],point[maxn],next[maxn],now,match[maxn];

bool visit[maxn];

void add(int x,int y)

{

    next[++now]=head[x];

    head[x]=now;

    point[now]=y;

}

int dfs(int k)

{

    for(int i=head[k];i;i=next[i])

    {

        int u=point[i];

        if(visit[u]==0)

        {

            visit[u]=1;

            if(match[u]==-1 || dfs(match[u]))

            {

                match[u]=k;

                return 1;

            }

        }

    }

    return 0;

}

int main()

{

    int n,m;

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

    {

        int ans=0,nn,x;

        now=0;

        memset(head,0,sizeof(head));

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

        {

            scanf("%d",&nn);

            for(int j=1;j<=nn;j++)

            {

                scanf("%d",&x);

                add(i,x);

            }

        }

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

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

        {

            memset(visit,0,sizeof(visit));

            if(dfs(i)==1)ans++;

        }

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

    }

    return 0;

}

poj 2239 Selecting Courses

题目大意:一个人要选课,一周有n节课,每节课要在一周的某些时间上,问最多能选多

 

少课

同样很裸的匹配。。。可能边出太大 C++ AC G++ WA

//poj2239

#include <stdio.h>

#include <iostream>

#include<queue>

#include <string.h>

#include <algorithm>

#define maxn 10000000

#define maxm 10001

#define esp 0.001

using namespace std;

int head[300],point[maxn],next[maxn],now,match[300];

bool visit[300];

void add(int x,int y)

{

    next[++now]=head[x];

    head[x]=now;

    point[now]=y;

}

int dfs(int k)

{

    for(int i=head[k];i;i=next[i])

    {

        int u=point[i];

        if(!visit[u])

        {

            visit[u]=1;

            if(match[u]==-1||dfs(match[u]))

            {

                match[u]=k;

                return 1;

            }

        }

    }

    return 0;

}

int main()

{

    int n,nn,x,y;

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

    {

        now=0;

        memset(head,0,sizeof(head));

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

        {

            scanf("%d",&nn);

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

            {

                scanf("%d%d",&x,&y);

                add(j,(x-1)*12+y);

            }

        }

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

        int ans=0;

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

        {

            memset(visit,0,sizeof(visit));

            if(dfs(i)==1)ans++;

        }

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

    }

    return 0;

}

 

题目大意:n*m的矩阵,某些格子有水,要用1*k(k随便)的木板盖住水,并且不能盖住没

 

有水的青草部分

思路:和上海邀请赛几乎一样的建图,乱搞一通就可以

//poj2226

#include <stdio.h>

#include <iostream>

#include<queue>

#include <string.h>

#include <algorithm>

#define maxn 900

#define maxm 50090

#define esp 0.001

using namespace std;

int head[maxn],point[maxm],next[maxm],now=0,match[maxn];

int map[maxn][maxn];

bool visit[maxn];

char ch[maxn];

void add(int x,int y){

    next[++now]=head[x];head[x]=now;point[now]=y;

}

int dfs(int k){

    for(int i=head[k];i;i=next[i])if(!visit[point[i]]){

        int u=point[i];visit[u]=1;

        if(match[u]==-1||dfs(match[u])){

            match[u]=k;return 1;

        }

    }

    return 0;

}

int main()

{

    int n,m,h=0,g=0,ans=0;

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

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

        scanf("%s",ch+1);

        for(int j=1;j<=m;j++)

            if(ch[j]==‘*‘)map[i][j]=(map[i][j-1]==0)?++h:map[i][j-1];

    }

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

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

            if(map[j][i]!=0)

                add(map[j][i],map[j-1][i]==0?++g:g);

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

    for(int i=1;i<=h;i++){

        memset(visit,0,sizeof(visit));if(dfs(i))ans++;

    }

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

    return 0;

}

二分图水题三发