Time Limit: 1000MS | Memory Limit: 10000K | |
Total Submissions: 20547 | Accepted: 9263 |
Description
Given the preferences of the cows, compute the maximum number of milk-producing assignments of cows to stalls that is possible.
Input
Output
Sample Input
5 5 2 2 5 3 2 3 4 2 1 5 3 1 2 5 1 2
Sample Output
4
題意:n頭牛,m個位置,每頭牛可以待在s個位置上,給每個牛分配一個位置,求問最多幾頭牛可以分配到位置。
這是二分圖匹配的基礎題,也可以用最大流來做,直接貼代碼。。
二分圖匹配:
#include <cstdio>
#include <iostream>
#include <algorithm>
#include <cstring>
#define maxn 205
using namespace std;
int maps[maxn][maxn], vis[maxn], link[maxn];
int n, m;
bool Find(int x)
{
for(int i = 1; i <= m; i++)
{
if(vis[i] == 0 && maps[x][i] == 1)
{
vis[i] = 1;
if(link[i] == 0 || Find(link[i]))
{
link[i] = x;
return true;
}
}
}
return false;
}
int main()
{
int x, y;
while(scanf("%d%d", &n, &m) != EOF)
{
memset(maps, 0, sizeof(maps));
memset(link, 0, sizeof(link));
for(int i = 1; i <= n; i++)
{
scanf("%d", &x);
for(int j = 0; j < x; j++)
{
scanf("%d", &y);
maps[i][y] = 1;
}
}
int ans = 0;
for(int i = 1; i <= n; i++)
{
memset(vis, 0, sizeof(vis));
if(Find(i))
ans++;
}
printf("%d\n", ans);
}
}
網絡流最大流:
#include <cstdio>
#include <iostream>
#include <algorithm>
#include <cstring>
#define maxn 505
using namespace std;
int n, m;
int maps[maxn][maxn], q[maxn * maxn];
int d[maxn];//記錄每個點所在的層
int BFS()//BFS分層,判斷是否存在增廣路
{
memset(d, -1, sizeof(d));
d[0] = 0;
int f, r;
f = 1;
r = 1;
q[r++] = 0;
while(f < r)
{
int x = q[f++];
for(int i = 0; i <= n + m + 1; i++)
{
if(d[i] < 0 && maps[x][i] > 0)
{
d[i] = d[x] + 1;
q[r++] = i;
}
}
}
if(d[n + m + 1] > 0)
return 1;
else
return 0;
}
int Find(int x, int v)//找出某一條增廣路的最大流
{
int a;
if(x == n + m + 1)
return v;
for(int i = 0; i <= n + m + 1; i++)
{
if(maps[x][i] > 0 && d[i] == d[x] + 1 && (a = Find(i, min(v, maps[x][i]))))//x到i有流量 且 i是x的下一層 且 i到匯點存在最大流
{
maps[x][i] -= a;//增廣路
maps[i][x] += a;//回退邊
return a;
}
}
return 0;
}
int main()
{
int x, y, t;
while(scanf("%d%d", &n, &m) != EOF)
{
memset(maps, 0, sizeof(maps));
for(int i = 1; i <= n; i ++)
{
scanf("%d", &x);
for(int j = 1; j <= x; j ++)
{
scanf("%d", &y);
maps[i][n + y] = 1;
}
}
for(int i = 1; i <= n; i++)
maps[0][i] = 1;
for(int i = n + 1; i <= n + m; i++)
maps[i][n + m + 1] = 1;
// for(int i = 0; i <= n + m + 1; i++)
// {
// for(int j = 0; j <= n + m + 1; j++)
// {
// printf("%d ",maps[i][j]);
// }
// printf("\n");
// }
int ans = 0;
while(BFS())//BFS搜索判斷是否有從源點到匯點的通路
{
while(t = Find(0, 2000000005))//查找增廣路,求其最大流
ans += t;
}
printf("%d\n", ans);
}
}