D - 棋盘游戏 - HDU 1281(二分图匹配)
分析:先求出来最大匹配数,然后用匹配的点一个一个去除看看能否达到最大匹配,能的话就是关键点(很暴力啊),不过竟然才31ms
*****************************************************************
#include<stdio.h>
#include<string.h>
#include<algorithm>
using namespace std;
const int MAXN = 105;
bool G[MAXN][MAXN], used[MAXN];
bool Find(int i, int N, int p[])
{
for(int j=1; j<=N; j++)
{
if(G[i][j] && used[j] == false)
{
used[j] = true;
if(!p[j] || Find(p[j], N, p))
{
p[j] = i;
return true;
}
}
}
return false;
}
int XYL(int p[], int M, int N)
{
int ans = 0;
for(int i=1; i<=M; i++)
{
memset(used, false, sizeof(used));
if(Find(i, N, p) == true)
ans++;
}
return ans;
}
int main()
{
int N, M, T, t=1;
while(scanf("%d%d%d", &M, &N, &T) != EOF)
{
int i, u, v;
int p1[MAXN]={0}, p2[MAXN]={0};
memset(G, false, sizeof(G));
while(T--)
{
scanf("%d%d", &u, &v);
G[u][v] = true;
}
int Max = XYL(p1, M, N);
int imp=0;
for(i=1; i<=N; i++)
{
if(p1[i])
{
memset(p2, 0, sizeof(p2));
G[ p1[i] ][i] = false;
if(XYL(p2, M, N) < Max)
imp++;
G[ p1[i] ][i] = true;
}
}
printf("Board %d have %d important blanks for %d chessmen.\n", t++, imp, Max);
}
#include<string.h>
#include<algorithm>
using namespace std;
const int MAXN = 105;
bool G[MAXN][MAXN], used[MAXN];
bool Find(int i, int N, int p[])
{
for(int j=1; j<=N; j++)
{
if(G[i][j] && used[j] == false)
{
used[j] = true;
if(!p[j] || Find(p[j], N, p))
{
p[j] = i;
return true;
}
}
}
return false;
}
int XYL(int p[], int M, int N)
{
int ans = 0;
for(int i=1; i<=M; i++)
{
memset(used, false, sizeof(used));
if(Find(i, N, p) == true)
ans++;
}
return ans;
}
int main()
{
int N, M, T, t=1;
while(scanf("%d%d%d", &M, &N, &T) != EOF)
{
int i, u, v;
int p1[MAXN]={0}, p2[MAXN]={0};
memset(G, false, sizeof(G));
while(T--)
{
scanf("%d%d", &u, &v);
G[u][v] = true;
}
int Max = XYL(p1, M, N);
int imp=0;
for(i=1; i<=N; i++)
{
if(p1[i])
{
memset(p2, 0, sizeof(p2));
G[ p1[i] ][i] = false;
if(XYL(p2, M, N) < Max)
imp++;
G[ p1[i] ][i] = true;
}
}
printf("Board %d have %d important blanks for %d chessmen.\n", t++, imp, Max);
}
}