您的位置:首页 > 其它

HDU 1325 Is It A Tree?

2017-04-08 20:19 357 查看
传送门

这个题是判断是否为树。

树的边是有向的,树也可以为空。

代码里面,
s
指子结点集,
total
指结点集,
v
指边集。

还有一个坑,最后结束标志是负数而不一定
-1


#include <iostream>
#include <algorithm>
#include <vector>
#include <cstring>
#include <unordered_set>
using namespace std;

const int MAXN = 1e6;
int a, b;
int c = 1;
int conn = 0;
int pre[MAXN];

struct Edge
{
int from, to;
};
vector<Edge> v;
unordered_set<int> s;
unordered_set<int> total;

int f(int n)
{
int f0 = n, f1 = n;
int t;
for (; pre[f0] > 0;)
{
f0 = pre[f0];
}
for (; pre[f1] > 0;)
{
t = f1;
f1 = pre[f1];
pre[t] = f0;
}
return f0;
}

bool u(int n1, int n2)
{
int f1 = f(n1);
int f2 = f(n2);
if (f1 != f2)
{
conn++;
if (pre[f1] <= pre[f2])
{
pre[f1] += pre[f2];
pre[f2] = f1;
}
else
{
pre[f2] += pre[f1];
pre[f1] = f2;
}
return true;
}
return false;
}

void judge()
{
if (v.size() == 0)
{
printf("Case %d is a tree.\n", c);
return;
}
if (v.size() != s.size())
{
printf("Case %d is not a tree.\n", c);     // 判定重指
return;
}
for (int i = 0; i < v.size(); i++)
{
if (!u(v[i].from, v[i].to))
{
printf("Case %d is not a tree.\n", c);  // 判定一切环,包括有环连通图和有环非连通图
return;
}
}
if (conn + 1 != total.size())   // 此时conn已经等于v.size()
{
printf("Case %d is not a tree.\n", c);     // 判定无环非连通图
return;
}
printf("Case %d is a tree.\n", c);
}
// 顺便说一句,v.size()+1!=total.size()应付不了有环非连通图
int main()
{
memset(pre, -1, sizeof pre);
for (; ~scanf("%d%d", &a, &b);)
{
if (a < 0) break;   // 坑!
if (a == 0)
{
judge();
memset(pre, -1, sizeof pre);
c++;
conn = 0;
v.clear();
s.clear();
total.clear();
continue;
}
v.push_back({ a,b });
s.insert(b);
total.insert(a);
total.insert(b);
}

return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: