CodeForces - 763A(并查集/思维)

题意

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;
}

  

posted @ 2019-12-08 09:27  MCQ1999  阅读(211)  评论(0编辑  收藏  举报