Codeforces Round #318 [RussianCodeCup Thanks-Round] (Div. 2) E DFS



链接:戳这里


E. Bear and Drawing
time limit per test1 second
memory limit per test256 megabytes
inputstandard input
outputstandard 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).

Examples
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


题意:

给出一棵树,然后问你能不能在两行格点里面画出这棵树


思路:

首先分析一下,对于一个根节点如果有三颗或者三颗以上的子树的叶子节点>=3,肯定是不行的

还需要考虑的是,当一个根节点已经有了两个子树的叶子节点>=3了,现在在来一颗子树,但是这颗子树不是链的话,也不行。然后就深搜吧

对于节点大于等于3的好说,但是需要处理是不是链的。嗯 我还是看了看别人的处理方式。自己太弱了


代码:

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<string>
#include<vector>
#include <ctime>
#include<queue>
#include<set>
#include<map>
#include<stack>
#include<iomanip>
#include<cmath>
#define mst(ss,b) memset((ss),(b),sizeof(ss))
#define maxn 0x3f3f3f3f
#define MAX 1000100
///#pragma comment(linker, "/STACK:102400000,102400000")
typedef long long ll;
typedef unsigned long long ull;
#define INF (1ll<<60)-1
using namespace std;
int n;
struct edge{
    int v,next;
}e[500100];
int head[100100],tot=0;
void Add(int u,int v){
    e[tot].v=v;
    e[tot].next=head[u];
    head[u]=tot++;
}
int res[100100];
int deep[100100];
int vis[100100];
void DFS(int u){
    vis[u]=1;
    for(int i=head[u];i!=-1;i=e[i].next){
        int v=e[i].v;
        if(deep[v]<=2 && !vis[v]) DFS(v);
    }
}
int main(){
    mst(head,-1);
    scanf("%d",&n);
    for(int i=1;i<n;i++){
        int u,v;
        scanf("%d%d",&u,&v);
        Add(u,v);
        Add(v,u);
        deep[u]++;
        deep[v]++;
    }
    for(int i=1;i<=n;i++){
        if(deep[i]==1) DFS(i);
    }
    for(int i=1;i<=n;i++){
        if(!vis[i]){
            for(int j=head[i];j!=-1;j=e[j].next){
                int v=e[j].v;
                if(vis[v]){
                    res[i]=min(res[i]+1,2);
                }
            }
        }
    }
    for(int u=1;u<=n;u++){
        if(!vis[u]){
            int cnt=0;
            for(int i=head[u];i!=-1;i=e[i].next){
                int v=e[i].v;
                if(!vis[v] && deep[v]-res[v]>1) cnt++;
            }
            if(cnt>2) {
                cout<<"No"<<endl;
                return 0;
            }
        }
    }
    cout<<"Yes"<<endl;
    return 0;
}
/*
20
5 15
20 4
11 18
1 14
18 2
14 17
8 10
13 1
11 6
14 16
12 8
9 3
13 15
8 17
3 13
1 18
17 7
9 20
19 12

13
1 2
1 3
1 4
2 5
2 6
2 7
4 11
4 12
4 13
3 8
8 9
8 10
*/


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值