http://acm.hust.edu.cn/vjudge/problem/viewProblem.action?id=28175
给一个图,n个点,m个边
要用黑白两种点间或把整个图覆盖
最少的黑点/白点个数,如果不能输出-1
【 //单独的节点在本题题意下需要染色】
直接dfs跑一遍二分图染色,注意,可能存在多个联通块,也就是跑多次dfs 。
每次跑完一个联通块 累加一下最少节点数
最后输出,任一联通块无法二分图染色则输出 -1 结束程序
#include <cstdio>
#include <cmath>
#include <cstring>
#include <string>
#include <algorithm>
#include <queue>
#include <map>
#include <set>
#include <vector>
#include <iostream>
using namespace std;
const double pi=acos(-1.0);
double eps=0.000001;
int min(int a,int b)
{return a<b?a:b;}
int max(int a,int b)
{return a>b?a:b;}
vector<int> mp[205];
int col[205];
int num,vaild;
int bin(int x)
{
int i;
num++; //总共染色点数
if (col[x]==1) vaild++; //黑子
for (i=0;i<mp[x].size();i++)
{
int v=mp[x][i];
if (col[v]==col[x]) return 0;
if (!col[v])
{
col[v]=3-col[x];
if (bin(v)==0) return 0;
}
}
return 1;
}
int main()
{
int n,m;
int t;cin>>t;
while(t--)
{
cin>>n>>m;
int x,y,i;
for (i=0;i<n;i++) mp[i].clear();
for (i=1;i<=m;i++)
{
scanf("%d%d",&x,&y);
mp[x].push_back(y);
mp[y].push_back(x);
}
int flag=0;
int sum=0;
memset(col,0,sizeof col);
for (i=0;i<n;i++)
{
if (col[i])continue;
col[i]=1;
vaild=num=0;
int ret=bin(i);
if (!ret) {printf("-1\n");flag=1;break;}
else
{
if (num==1) sum++; //【单独的节点在本题题意下需要染色】
else sum+=min(vaild,num-vaild);
}
}
if (flag)continue;
printf("%d\n",sum);
}
return 0;
}

本文介绍了一种基于深度优先搜索(DFS)的二分图染色算法,用于解决图论问题中寻找最少黑点/白点覆盖的问题。通过遍历每个连通块并尝试用两种颜色交替染色所有节点来实现,适用于处理不相连的多个子图。

1753

被折叠的 条评论
为什么被折叠?



