You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

71 lines
2.9 KiB

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

#include <bits/stdc++.h>
using namespace std;
const int N = 1e5 + 10, M = N << 1;
/*
7e5+10
=700000*4/1024/1024=2.67MB
这内存也不大啊为啥会SE呢不是说64MB的上限吗?
被卡的好难受,这是逼我去用并查集+公式解题啊!
*/
//邻接表
int e[M], h[N], idx, ne[M];
void add(int a, int b) {
e[idx] = b, ne[idx] = h[a], h[a] = idx++;
}
bool st[N]; //标识某个节点号是不是使用过
bool vis[N]; //是不是在dfs过程中搜索过
int flag; // true:满足两个条件 false:不满足两个条件 (1)是不是有环,要求无环 (2)是不是连通,要求连通
// dfs无向图判环
void dfs(int u, int fa) { //从u节点开始搜索它的父节点是fa输入fa的意义在于不能走回头路防止死循环
vis[u] = true; //标识u已经搜索过了
for (int i = h[u]; ~i; i = ne[i]) { //枚举u的每一条出边
int j = e[i];
if (j == fa) continue; //放过来源节点
if (vis[j]) { //如果j被搜索过说明有环
flag = false; //标识有环
return;
}
dfs(j, u); //继续搜索j节点它的父节点是u
}
}
//每组输入的清空与初始化
void init() {
memset(st, 0, sizeof(st));
memset(vis, 0, sizeof(vis));
memset(h, -1, sizeof h);
idx = 0;
}
int main() {
int a, b;
init();
while (scanf("%d%d", &a, &b) && ~a && ~b) {
if (a && b) { //如果输入的a,b是两个非零数字
st[a] = st[b] = true; //标识a,b已使用
add(a, b), add(b, a); //添加两条无向边
} else { //如果输入的是两个0,描述是一组数据输入结束
flag = true; //默认是无环+连通图
// 1、检查是不是无环
for (int i = 1; i < N; i++) //枚举每个节点
if (st[i]) { //如果i节点使用过
//从找到的第一个使用过的节点开始进行dfs扫描
dfs(i, i);
break;
}
// 2、检查连通性
if (flag) { //扫描完的结果1、找到了环2、没有找到环
//下面将现次枚举每个使用过的点,查看它是不是在dfs过程中被扫描到了如果存在使过未扫到的点则说明不连通
for (int i = 1; i < N; i++)
if (st[i] && !vis[i]) { //如果存在出现过但dfs没有扫描到的点说明不连通
flag = false;
break;
}
}
flag ? puts("Yes") : puts("No"); //两个条件都满足输出Yes,否则输出No
init(); //因为要输入下一组数据,需要清空状态数组
}
}
return 0;
}