#include <iostream>
#include <cstdio>
#include <cstring>
#include <vector>
const int maxn = 110000;
const int maxm = 110000;
using namespace std;
typedef struct node {
int to;
int next;
}node;
node edge[maxm];
int head[maxn];
int ednum = 1;
int s = 0, t = 0;
int que[maxm+maxm];
int flag[maxn];
int indeg[maxn];
vector<int> v;
int init() {
v.clear();
memset(head, 0, sizeof(head));
memset(indeg, 0, sizeof(indeg));
memset(flag, 0, sizeof(flag));
ednum = 1;
while (1) {
scanf("%d%d", &s, &t);
if (s<0 && t<0) {
return -1;
}
if (s==0 && t==0) {
return 1;
}
if (!flag[s]) {
flag[s] = 1;
v.push_back(s);
}
if (!flag[t]) {
flag[t] = 1;
v.push_back(t);
}
indeg[t]++;
edge[ednum].to = t;
edge[ednum].next = head[s];
head[s] = ednum;
ednum++;
}
return 0;
}
int work() {
int tot = 0, root = 0;
for (int i = 0; i < (int)v.size(); i++) {
if (indeg[v[i]] > 1) {
return 0;
}
if (indeg[v[i]] == 0) {
root = v[i];
tot++;
if (tot > 1) {
return 0;
}
}
}
if (tot == 0) {
return 1;
}
memset(flag, 0, sizeof(flag));
int iq = 0;
que[iq++] = root;
flag[root] = 1;
for (int i = 0; i < iq; i++) {
int top = que[i];
for (int k = head[top]; k != 0; k = edge[k].next) {
int to = edge[k].to;
if (flag[to] == 1) {
return 0;
}
else {
flag[to] = 1;
que[iq++] = to;
}
}
}
for (int i = 0; i < (int)v.size(); i++) {
if (!flag[v[i]]) {
return 0;
}
}
return 1;
}
int main()
{
int c = 1;
while (1) {
int start = init();
if (start == 1) {
int ok = work();
if (ok) {
printf("Case %d is a tree.\n", c++);
}
else {
printf("Case %d is not a tree.\n", c++);
}
}
if (start == -1) {
break;
}
}
return 0;
}
poj 1308题目稍微改动,此题用并查集也很优)hdu1325(Is it a tree)
最新推荐文章于 2022-11-03 16:27:51 发布
本文提供了一种使用邻接表和拓扑排序算法来判断输入是否构成树的有效方法。通过初始化图结构,记录节点的入度,并进行拓扑排序验证图是否为树。
&spm=1001.2101.3001.5002&articleId=8095477&d=1&t=3&u=a9f387f26b424f6c9c0de5bd30656a8a)
2710

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



