• 二分图水题四发


    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 ",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 ",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 ",ans);

        return 0;

    }

    //poj2536

    #include <stdio.h>

    #include <iostream>

    #include<queue>

    #include <string.h>

    #include <algorithm>

    #define maxn 9000

    #define maxm 500090

    #define esp 0.001

    using namespace std;

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

    bool visit[maxn];

    double x[maxn],xx[maxn],y[maxn],yy[maxn];

    void add(int x,int y)

    {

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

        head[x]=now;

        point[now]=y;

    }

    double dist(int i,int j)

    {

        return (x[i]-xx[j])*(x[i]-xx[j])+(y[i]-yy[j])*(y[i]-yy[j]);

    }

    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,s,v;

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

        {

            now=0;

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

            for(int i=1;i<=n;i++)scanf("%lf%lf",&x[i],&y[i]);

            for(int i=1;i<=m;i++)scanf("%lf%lf",&xx[i],&yy[i]);

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

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

                    if(dist(i,j)<=s*s*v*v)

                    add(i,j);

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

            int ans=0;

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

            {

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

                if(dfs(i))ans++;

            }

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

        }

        return 0;

    }

  • 相关阅读:
    POJ 2431 Expedition(探险)
    POJ 3253 Fence Repair(修篱笆)
    POJ 3069 Saruman's Army(萨鲁曼军)
    POJ 3617 Best Cow Line(最佳奶牛队伍)
    [蓝桥杯] 排它平方数
    [蓝桥杯] 小朋友排队
    UVA315 Network 连通图割点
    POJ 1236 Network of Schools 连通图缩点
    poj1061 青蛙的约会
    拓展欧几里
  • 原文地址:https://www.cnblogs.com/philippica/p/4065566.html
Copyright © 2020-2023  润新知