E. Bear and Drawing

     E. Bear and Drawing
time limit per test
1 second
memory limit per test
256 megabytes
input
standard input
output
standard output

Limak is a little bear who learns to draw. People usually start with houses, fences and flowers but why would bears do it? Limak lives in the forest and he decides to draw a tree.

Recall that tree is a connected graph consisting of n vertices and n - 1 edges.

Limak chose a tree with n vertices. He has infinite strip of paper with two parallel rows of dots. Little bear wants to assign vertices of a tree to some n distinct dots on a paper so that edges would intersect only at their endpoints — drawn tree must be planar. Below you can see one of correct drawings for the first sample test.

Is it possible for Limak to draw chosen tree?

Input

The first line contains single integer n (1 ≤ n ≤ 105).

Next n - 1 lines contain description of a tree. i-th of them contains two space-separated integers ai and bi(1 ≤ ai, bi ≤ n, ai ≠ bi) denoting an edge between vertices ai and bi. It's guaranteed that given description forms a tree.

Output

Print "Yes" (without the quotes) if Limak can draw chosen tree. Otherwise, print "No" (without the quotes).

Sample test(s)
input
8
1 2
1 3
1 6
6 4
6 7
6 5
7 8
output
Yes
input
13
1 2
1 3
1 4
2 5
2 6
2 7
3 8
3 9
3 10
4 11
4 12
4 13
output
No

我们想如果一个点 连接着 大于等于两颗树是多叉树的话,那么我们就可以认为这个是无解的(除非其中一颗树是直接连接在该结点上的)。
#include<cstdio>
#include <iostream>
#include <string.h>
#include <vector>
using namespace std;
const int maxn = 100000 + 5;
vector<int> G[maxn];
int leg[maxn];
bool del[maxn];
void dfs(int cur, int per=-1)
{
      if(G[cur].size()<=2)
        {
             del[cur]=true;
             int siz=G[cur].size();
             for(int i=0; i<siz; i++)
                {
                     int b=G[cur][i];
                     if(b == per) continue;
                     dfs(b,cur);
                }
        }

}
int main() {
    int n;
    while(scanf("%d",&n)==1)
    {
        memset(del,false,sizeof(del));
        memset(leg,0,sizeof(leg));
         for(int i=1; i<=n; i++)G[i].clear();
        for(int i=1; i<n; i++)
            {
                int a,b;
                 scanf("%d%d",&a,&b);
                 G[a].push_back(b);
                 G[b].push_back(a);
            }
            for(int i=1; i<=n; i++)
            if(G[i].size() ==1 ){
                dfs(i);
            }
            for(int a=1; a<=n; a++)
            {
                int siz=G[a].size();
                for(int j = 0; j<siz; j++)
                    {
                         int b=G[a][j];
                         if(del[b])
                            {
                                leg[a]=min(leg[a]+1,2);
                            }
                    }
            }
            bool falg=true;
            for(int a=1; a<=n; a++)
                if(del[a]==false){
                     int cnt=0;
                     for(int j=0; j<G[a].size(); j++)
                        {
                            int b=G[a][j];
                           if(del[b]==false&&G[b].size()-leg[b]>1) cnt++;
                        }
                      if(cnt>2){
                        falg=false; break;
                      }
                }
                if(falg)puts("YES");
                else puts("NO");
    }
    return 0;
}
View Code

 

转载于:https://www.cnblogs.com/Opaser/p/4780243.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值