标签:二分图最小顶点覆盖
二分图最小顶点覆盖问题
题目给出n*n的图 和m个炸弹的位置 每枚炸弹可同时炸掉一行或一列 即相同x所匹配的y看为一点 算出一个顶点集使每边所连点至少在其中出现一个 这个最小的顶点集即为所求结果
二分图最大匹配=最小顶点数
代码如下:
#include <cstdio>
#include <cstdlib>
#include <cstring>
using namespace std;
int link[505],k,n;
bool mp[505][505];
bool vis[505];
bool can(int s)
{
int i;
for(i = 1; i <= n; ++i)
{
if(!vis[i] && mp[s][i])
{
vis[i] = 1;
if(link[i] == -1 || can(link[i]))
{
link[i] = s;
return 1;
}
vis[i] = 0;
}
}
return 0;
}
int main()
{
int i,j,cnt,x,y;
scanf("%d %d",&n,&k);
memset(mp,0,sizeof(mp));
for(i = 0; i < k; ++i)
{
scanf("%d %d",&x,&y);
mp[x][y] = 1;
}
memset(link,-1,sizeof(link));
cnt = 0;
for(i = 1; i <= n; ++i)
{
memset(vis,0,sizeof(vis));
if(can(i)) cnt++;
}
printf("%d\n",cnt);
return 0;
}
后来看了discuss 发现用邻接链优化速度会提高很多 毕竟是稀疏图。。
代码如下:
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <vector>
using namespace std;
vector <int> head[505];
int link[505],k,n;
bool vis[505];
bool can(int s)
{
int i,v;
for(i = 0; i < head[s].size(); ++i)
{
v = head[s][i];
if(!vis[v])
{
vis[v] = 1;
if(link[v] == -1 || can(link[v]))
{
link[v] = s;
return 1;
}
vis[v] = 0;
}
}
return 0;
}
int main()
{
int i,j,cnt,x,y;
scanf("%d %d",&n,&k);
for(i = 0; i < k; ++i)
{
scanf("%d %d",&x,&y);
head[x].push_back(y);
}
memset(link,-1,sizeof(link));
cnt = 0;
for(i = 1; i <= n; ++i)
{
memset(vis,0,sizeof(vis));
if(can(i)) cnt++;
}
printf("%d\n",cnt);
return 0;
}
版权声明:本文为博主原创文章,未经博主允许不得转载。
标签:二分图最小顶点覆盖
原文地址:http://blog.csdn.net/challengerrumble/article/details/47099899