题意看了个大概,貌似就是有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>