首先可以推断出图要是联通的并且要有奇数条边的回路才能输出YES,因为从一个点开始沿着一个环分别向左右两个方向遍历,只有当前环的结点数为奇数的时候左右两个方向到同一个点是一奇一偶的,
这样就说明存在某一时刻可以让贼出现在各个位置,因为这个点奇偶都可达,那么只需要进行一次BFS并且01染色就可以了
#include <iostream>
#include <vector>
#include <queue>
using namespace std;
const int size = 110000;
int color[size];//表示第i个点被染的颜色
int n, m;
vector <int> mapp[size];
queue <int> Que;
void init()
{
for (int i = 0; i <= n; i ++){
mapp[i].clear();
}
}
bool bfs(int s)//从S点起开始查找当前图mapp中有无奇数条边的回路
{
while (!Que.empty())Que.pop();
Que.push(s);
color[s] = 0;
int num = 1;
bool check = false;
while (!Que.empty()){
int pre = Que.front();
Que.pop();
for (int i = 0; i < mapp[pre].size(); i ++){
int k = mapp[pre][i];
if (color[pre] == color[k]){//如果前一个点后它的后继染色点相同则说明有奇数回路
check = true;
continue;
}
if (color[k] == -1){
num ++;
color[k] = color[pre]^1;
Que.push(k);
}
}
}
if (check && num == n)return true; //当前图是连通图且不能 构成二分图(存在奇数条边的回路)
return false;
}
int main()
{
int t;
int s;
scanf("%d", &t);
int nc = 0;
while (t --){
init();
scanf("%d%d%d", &n, &m, &s);
while (m --){
int a, b;
scanf("%d%d", &a, &b);
mapp[a].push_back(b);
mapp[b].push_back(a);
}
memset(color, -1, sizeof(color));
printf("Case %d: ", ++nc);
bfs(s)?printf("YES\n"):printf("NO\n");
}
return 0;
}
这样就说明存在某一时刻可以让贼出现在各个位置,因为这个点奇偶都可达,那么只需要进行一次BFS并且01染色就可以了
#include <iostream>
#include <vector>
#include <queue>
using namespace std;
const int size = 110000;
int color[size];//表示第i个点被染的颜色
int n, m;
vector <int> mapp[size];
queue <int> Que;
void init()
{
for (int i = 0; i <= n; i ++){
mapp[i].clear();
}
}
bool bfs(int s)//从S点起开始查找当前图mapp中有无奇数条边的回路
{
while (!Que.empty())Que.pop();
Que.push(s);
color[s] = 0;
int num = 1;
bool check = false;
while (!Que.empty()){
int pre = Que.front();
Que.pop();
for (int i = 0; i < mapp[pre].size(); i ++){
int k = mapp[pre][i];
if (color[pre] == color[k]){//如果前一个点后它的后继染色点相同则说明有奇数回路
check = true;
continue;
}
if (color[k] == -1){
num ++;
color[k] = color[pre]^1;
Que.push(k);
}
}
}
if (check && num == n)return true; //当前图是连通图且不能 构成二分图(存在奇数条边的回路)
return false;
}
int main()
{
int t;
int s;
scanf("%d", &t);
int nc = 0;
while (t --){
init();
scanf("%d%d%d", &n, &m, &s);
while (m --){
int a, b;
scanf("%d%d", &a, &b);
mapp[a].push_back(b);
mapp[b].push_back(a);
}
memset(color, -1, sizeof(color));
printf("Case %d: ", ++nc);
bfs(s)?printf("YES\n"):printf("NO\n");
}
return 0;
}