两种写法 第一种gg了 不是太理解,以后再来弄懂,以行和列建二分图 左边行右边表示列 求最大二分匹配
重要点求法就是枚举每一个点 判断最大匹配有没有改变
//1
#include <string.h>
#include <algorithm>
#include <iostream>
#include <stdio.h>
using namespace std;
void getmap();
int hungarian();
bool dfs(int u);
int n, m, k;
int solve();
int maxmatching, imdot = 0;
int plan[110][110];
int used[110], matching[110], dotx[110110], doty[110110];
int main()
{
while(scanf("%d%d%d", &n, &m, &k) != EOF)
{
memset(plan, 0, sizeof(plan));
getmap();
maxmatching = hungarian();
// imdot = solve();
printf("%d %d", maxmatching, imdot);
}
}
void getmap()
{
for(int i = 0; i < k; i++)
{
int x, y;
scanf("%d%d", &x, &y);
plan[x][y] = 1;
dotx[i] = x;
doty[i] = y;
}
}
int hungarian()
{
int ans = 0;
memset(matching, -1, sizeof(matching));
for(int i = 0; i < k; i++)
{
memset(used, 0, sizeof(used));
if(dfs(dotx[i]))
ans++;
// printf("%d\n", ans);
}
return ans;
}
bool dfs(int u)
{
//int v;
for(int i = 0; i < k; i++)
{
if(plan[u][doty[i]] && !used[doty[i]])
{
printf("%d %d %d\n", u, doty[i], matching[doty[i]]);
used[doty[i]] = true;
if(matching[doty[i]] == -1 || dfs(matching[doty[i]]))
{
matching[doty[i]] = u;
return true;
}
}
}
return false;
}
int solve()
{
int ans = 0;
for(int i = 0; i < k; i++)
{
plan[dotx[i]][doty[i]] = 0;
int match1 = hungarian();
if(match1 < maxmatching)
ans++;
plan[dotx[i]][doty[i]] = 1;
}
return ans;
}
// 2
#include <string.h>
#include <algorithm>
#include <iostream>
#include <stdio.h>
using namespace std;
void getmap();
int hungarian();
bool dfs(int u);
int n, m, k;
int solve();
int maxmatching, imdot = 0;
int plan[110][110];
int used[110], matching[110], dotx[110110], doty[110110];
int main()
{
int cnt = 1;
while(scanf("%d%d%d", &n, &m, &k) != EOF)
{
memset(plan, 0, sizeof(plan));
getmap();
maxmatching = hungarian();
imdot = solve();
printf("Board %d have %d important blanks for %d chessmen.\n",cnt++ , imdot, maxmatching);
}
}
void getmap()
{
for(int i = 0; i < k; i++)
{
int x, y;
scanf("%d%d", &x, &y);
plan[x][y] = 1;
dotx[i] = x;
doty[i] = y;
}
}
int hungarian()
{
int ans = 0;
memset(matching, -1, sizeof(matching));
for(int i = 1; i <= n; i++)
{
memset(used, 0, sizeof(used));
if(dfs(i))
ans++;
//printf("%d\n", ans);
}
return ans;
}
bool dfs(int u)
{
//int v;
for(int i = 1; i <= m; i++)
{
if(plan[u][i] && !used[i])
{
// printf("%d %d %d\n", u, i, matching[i]);
used[i] = true;
if(matching[i] == -1 || dfs(matching[i]))
{
matching[i] = u;
return true;
}
}
}
return false;
}
int solve()
{
int ans = 0;
for(int i = 0; i < k; i++)
{
plan[dotx[i]][doty[i]] = 0;
int match1 = hungarian();
if(match1 < maxmatching)
ans++;
plan[dotx[i]][doty[i]] = 1;
}
return ans;
}