zoukankan      html  css  js  c++  java
  • CodeForces

    题意

    https://vjudge.net/problem/CodeForces-763A

    一棵无根树中各个节点被染上了一种颜色c[i]

    现在让你选择一个点作为根节点,使得这个根节点的所有儿子满足以该儿子节点的作为根的子树中所有点颜色均相同(不同儿子为根的子树颜色可以不同)

    思路

    俺的方法:

    暴力水过。用并查集把相同颜色的连了边的点缩点,然后枚举每个点作为答案,判断这个点所连的的所有点的所在相同颜色连通块的大小之和是否等于n-1即可(除去自己这个点)。

    正解:

    先计算每个点与所连的点的颜色不同的点数,把两端颜色不同的边数也记录。如果某个点与连的点的不同颜色的个数==所有颜色不同的边数,那么这个点就是满足条件的。

    这样想,作为根的这个点连的其他连通块肯定每个连通块颜色都是相同的,那么颜色不同的边只能在根这个点产生。

    代码

    俺的:

    #include<bits/stdc++.h>
    using namespace std;
    #define inf 0x3f3f3f3f
    #define ll long long
    const int N=100005;
    const int mod=1e9+7;
    const double eps=1e-8;
    const double PI = acos(-1.0);
    #define lowbit(x) (x&(-x))
    int c[N],pre[N];
    vector<int> g[N];
    int flag=0;
    int find(int x)
    {
        if(x==pre[x])
            return x;
        return pre[x]=find(pre[x]);
    }
    set<int> s[N];
    int main()
    {
        std::ios::sync_with_stdio(false);
        int n;
        cin>>n;
        for(int i=1; i<n; i++)
        {
            int u,v;
            cin>>u>>v;
            g[u].push_back(v);
            g[v].push_back(u);
        }
        int q,mx=0;
        for(int i=1; i<=n; i++)
        {
            cin>>c[i];
            pre[i]=i;
        }
        for(int i=1; i<=n; i++)
        {
            int sz=g[i].size();
            for(int j=0; j<sz; j++)
            {
                if(c[i]==c[g[i][j]])
                {
                    int fi=find(i),fj=find(g[i][j]);
                    if(fi!=fj)
                        pre[fj]=fi;
                }
            }
        }
        for(int i=1; i<=n; i++)
        {
            s[find(i)].insert(i);
        }
        int p,f=0;
        for(int i=1; i<=n; i++)
        {
            int sum=0;
            int sz=g[i].size();
            for(int j=0; j<sz; j++)
            {
                int v=g[i][j];
                sum+=s[find(v)].size();
            }
         //   cout<<i<<" "<<sum<<endl;
            if(s[i].size()!=1)
            {
                sum--;
            }
            if(sum==n-1)
            {
                p=i;
                flag=1;
                break;
            }
        }
        if(!flag)
            cout<<"NO"<<endl;
        else
        {
            cout<<"YES"<<endl;
            cout<<p<<endl;
        }
        return 0;
    }
    /*
    7
    1 7
    1 3
    1 4
    4 5
    1 2
    2 6
    3 2 1 2 2 2 2
    */
    /*
    8
    1 4
    2 4
    3 4
    4 8
    1 7
    2 5
    2 6
    2 1 8 2 1 1 2 6
    */
    

      

    正解:

    #include<bits/stdc++.h>
    using namespace std;
    #define inf 0x3f3f3f3f
    #define ll long long
    const int N=100005;
    const int mod=1e9+7;
    const double eps=1e-8;
    const double PI = acos(-1.0);
    #define lowbit(x) (x&(-x))
    int c[N],s[N],u[N],v[N];
    int main()
    {
        std::ios::sync_with_stdio(false);
        int n;
        cin>>n;
        for(int i=1; i<n; i++)
        {
            cin>>u[i]>>v[i];
        }
        int q,mx=0;
        for(int i=1; i<=n; i++)
        {
            cin>>c[i];
        }
        int sum=0;
        for(int i=1;i<n;i++)
        {
            if(c[u[i]]!=c[v[i]])
                s[u[i]]++,s[v[i]]++,sum++;
        }
        for(int i=1;i<=n;i++)
        {
            if(s[i]==sum)
            {
                cout<<"YES"<<endl<<i<<endl;
                return 0;
            }
        }
        cout<<"NO"<<endl;
        return 0;
    }
    

      

  • 相关阅读:
    xpath爬顶点页面信息
    urllib与urllib的区别
    爬虫代理IP
    前端js框架汇总
    scrapy的基本安装步骤
    Python+requests 爬取网站遇到中文乱码怎么办?
    爬虫笔记课后习题1
    至此记录点滴、、
    c++封装的发邮件类CSendMail
    Socket创建失败:10093错误
  • 原文地址:https://www.cnblogs.com/mcq1999/p/12004627.html
Copyright © 2011-2022 走看看