codeforces Bear and Drawing

来源:互联网 发布:淘宝专业差评 编辑:程序博客网 时间:2024/04/29 07:49

题目链接:http://codeforces.com/problemset/problem/573/C

题意

有一棵n个点的树, 然后有两行列无限点的, 问这棵树能否画出。 能输出Yes, 否则输出No。

分析:

对于一个点,它衍生出来的最左端的点和最右端的点可以衍生出 >2个点。除了最左边和最右边的点, 最多只能衍生出2个点, 而这些点只能衍生一个点。则对于每个连接数>2的点,最多只有两个点的连接数>=3.

AC代码:

#include<stdio.h>#include<string.h>#include<vector>#include<algorithm>using namespace std;const int maxn = 1e5 + 10;vector<int> G[maxn];int dg[maxn], d[maxn], vis[maxn];void dfs(int u){    vis[u] = 1;    for(int i = 0; i < G[u].size(); i++)    {        int v = G[u][i];        if(!vis[v] && dg[v]<=2)            dfs(v);    }}int main(){    int n, a, b, cnt;    bool flag;    scanf("%d", &n);    memset(vis, 0, sizeof(vis));    memset(dg, 0, sizeof(dg));    memset(d, 0, sizeof(d));    for(int i = 0; i <= n; i++)        G[i].clear();    for(int i = 1; i < n; i++)    {        scanf("%d%d", &a, &b);        dg[a]++;        dg[b]++;        G[a].push_back(b);        G[b].push_back(a);    }    for(int i = 1; i <= n; i++)        if(dg[i] == 1)            dfs(i);    for(int i = 1; i <= n; i++)        if(!vis[i])        {            for(int j = 0; j < G[i].size(); j++)            {                int v = G[i][j];                if(vis[v])                    d[i] = min(d[i]+1, 2);            }        }    flag = true;    for(int i = 1; i <= n; i++)        if(!vis[i])        {            cnt = 0;            for(int j = 0; j < G[i].size(); j++)            {                int v = G[i][j];                if(!vis[v] && dg[v]-d[v]>1)                    cnt++;            }            if(cnt > 2)            {                flag = false;                break;            }        }    if(flag)        puts("Yes");    else        puts("No");    return 0;}


0 0
原创粉丝点击