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

来源:互联网 发布:ck one 知乎 编辑:程序博客网 时间:2024/06/09 16:21

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

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

<span style="font-size:18px;">#include <cstdio>#include <cstring>#include <algorithm>#include <cmath>#define maxn 550using 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 550using 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
原创粉丝点击