これらの質問のタイトルはツリーを判断することですが、出力は異なります
定義付きのツリーを作成する
場合は、ツリーが何であるかを知っている必要があります。勉強しているとき、混乱していて、一般的な方向性を理解していません。一般的な方向性
は何ですか?木は間違いなく絵ですが、絵は必ずしも木ではありません。これらのいくつかの知識ポイントを理解することで、これを楽しくすることができます
两个字:图论
- 学位とは何ですか?学位は側面です。度は度数と度数に分けられます(エッジとエッジで)。ここに点Vがあり、Vを指すエッジは次数であり、Vから指摘される点は次数です。
- 木とは?度数が0のグラフは1つだけで、他の度数は1がツリーです。
ええと、ツリーとは何かが解決されると、すべての問題が解決されます。え?分からないの?次に、それらを1つずつリストします。
- 次数が0の1つのエントリのみが、ツリーにルートノードが1つしかないことを保証します。
- ルートノードを除いて、他のすべてのポイントには次数があります。これは、これが接続グラフでなければならないことを保証します(慎重に考えてください。次数が必要であることがわかります)
- ルートノードを除いて、他のポイントの強度はすべて1であり、各ポイントにルートノードが1つだけ存在することを保証します(これにより、グラフにリングが含まれないことも保証されます)。
したがって、この問題はチェックセットでも実行できます。操作は次のとおりです。
- 接続されたコンポーネントは1です(Find(i)== iの数は1のみです)
- そして、写真には輪がありません。(マージ操作で判断できます)
もちろん、この質問には幽霊がいます-たとえ意味がなくても、それは木です。
図の理由が空で設定することができない話題から、と感じKongjishiseそれが特別な文を追加することになり、......
これは木の性質で作られたコードのリストです。
#include <bits/stdc++.h>///注意poj不能用万能头,自行更改吧
using namespace std;
int T,n,a,b;
int e[100005];///入度
int book[100005];///标记这个点是否出现
int main()
{
int mx=0;///我要遍历存在的点。。这里是用数组下标,所以我要保存遍历到哪里
int cnt=1;///这个just是用来输出的时候看是第几个例子而已……不用管
int isp=1;///这就是判断是不是空集的标记
while(scanf("%d%d",&a,&b)!=EOF)
{
if(a+b<0)break;///-1 -1的时候结束
if(a==0 && b==0)///两个都是0的时候判断
{
int ans=0;///入度为0的个数(有几个根,很明显只能有一个根)
int flag=1;///是否除了根节点以外都是入度为1的呢?
for(int i=1;i<=mx;i++)
{
if(book[i] && e[i]==0)///判断出现并且入度为0,那就是根
{
ans++;
}
else if(book[i] && e[i]!=1)///不是根,那就判断入度是不是1
{
flag=0;
}
}
///hdu 1272的只有输出不一样!(HDU1325)(POJ1308)都是这个板子
if((flag==1 && ans==1) || isp)printf("Case %d is a tree.\n",cnt);
else printf("Case %d is not a tree.\n",cnt);
///这些都是初始化
memset(e,0,sizeof(e));
memset(book,0,sizeof(book));
mx=0;
cnt++;
isp=1;
}
else{
isp=0;
e[b]++;///入度
book[a]=1;///标记这个点是否出现
book[b]=1;
mx=(max(a,max(mx,b)));
}
}
return 0;
}