poj 1274 最大流或二分图,匈牙利算法

题意看了个大概,貌似就是有m头牛,n个坑,接下来是m行,代表第几头牛以及这头牛能在哪个坑里面吃草,要求输出同时最多有几头牛一起吃草

最大流解法:由源点向牛连边,牛连坑,坑连到汇点,每条边容量都是1,直接求最大流

<span style="font-size:18px;">#include <cstdio>
#include <cstring>
#include <algorithm>
#include <cmath>
#define maxn 550
using namespace std;
int map[maxn][maxn],tans;
int dis[maxn];
int q[maxn*maxn],f,r;
int n,m,ans,cow,stall;
int bfs(){
    memset(dis,-1,sizeof(dis));
    f = r = 0;
    q[r++] = 1;
    dis[1] = 0;
    while(f < r)
    {
        int x = q[f++];
        for(int i = 1; i <= n; i++)
            if(map[x][i] > 0 && dis[i] < 0)
        {
            dis[i] = dis[x] + 1;
            q[r++] = i;
        }
    }
    if(dis[n] > 0) return 1;
    else return 0;
}

int find(int x, int low){
    int i, a = 0;
    if(x == n) return low;
    for(int i = 1; i <= n; i++)
        if(dis[i] == dis[x] + 1 && map[x][i] > 0 && (a = find(i,min(low,map[x][i]))))
    {
        map[x][i] -= a;
        map[i][x] += a;
        return a;
    }
    return 0;
}
int main(){
    while(scanf("%d%d",&cow,&stall)!=EOF)
    {
        memset(map,0,sizeof(map));
        n = cow + stall + 2;
        int num;
        for(int i = 2; i < 2+cow; i++)
        {
            map[1][i] = 1;
            scanf("%d",&num);
            while(num--)
            {
                int tem;
                scanf("%d",&tem);
                map[i][1+cow+tem] = 1;
            }
        }
        for(int i = 2+cow; i < 2+cow+stall; i++)
            map[i][n] = 1;
        /*for(int i = 1; i <= 12; i++)
        {
            for(int j = 1; j <= 12; j++)
                printf("%d ",map[i][j]);
            printf("\n");
        }*/
        ans = 0;
        while(bfs())
        {
            while(tans = find(1,0x7fffffff))
                ans+=tans;
        }
        printf("%d\n",ans);
    }
}
</span>

二分图:匈牙利算法,对每个牛,找对应的坑,如果这头牛的坑被占了,就让占了这个坑的牛去找另一个,一直到找不到

AC代码:

<span style="font-size:18px;">#include <cstdio>
#include <cstring>
#include <algorithm>
#include <cmath>
#define maxn 550
using namespace std;
int map[maxn][maxn],tans;
int dis[maxn];
int q[maxn*maxn],f,r;
int n,m,ans,cow,stall;
int bfs(){
    memset(dis,-1,sizeof(dis));
    f = r = 0;
    q[r++] = 1;
    dis[1] = 0;
    while(f < r)
    {
        int x = q[f++];
        for(int i = 1; i <= n; i++)
            if(map[x][i] > 0 && dis[i] < 0)
        {
            dis[i] = dis[x] + 1;
            q[r++] = i;
        }
    }
    if(dis[n] > 0) return 1;
    else return 0;
}

int find(int x, int low){
    int i, a = 0;
    if(x == n) return low;
    for(int i = 1; i <= n; i++)
        if(dis[i] == dis[x] + 1 && map[x][i] > 0 && (a = find(i,min(low,map[x][i]))))
    {
        map[x][i] -= a;
        map[i][x] += a;
        return a;
    }
    return 0;
}
int main(){
    while(scanf("%d%d",&cow,&stall)!=EOF)
    {
        memset(map,0,sizeof(map));
        n = cow + stall + 2;
        int num;
        for(int i = 2; i < 2+cow; i++)
        {
            map[1][i] = 1;
            scanf("%d",&num);
            while(num--)
            {
                int tem;
                scanf("%d",&tem);
                map[i][1+cow+tem] = 1;
            }
        }
        for(int i = 2+cow; i < 2+cow+stall; i++)
            map[i][n] = 1;
        /*for(int i = 1; i <= 12; i++)
        {
            for(int j = 1; j <= 12; j++)
                printf("%d ",map[i][j]);
            printf("\n");
        }*/
        ans = 0;
        while(bfs())
        {
            while(tans = find(1,0x7fffffff))
                ans+=tans;
        }
        printf("%d\n",ans);
    }
}
</span>


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值