Cod sursa(job #2006249)

Utilizator stelian2000Stelian Chichirim stelian2000 Data 29 iulie 2017 02:59:03
Problema Paduri de multimi disjuncte Scor 0
Compilator cpp Status done
Runda Arhiva educationala Marime 2.05 kb
#include <cstdio>
#include <vector>
#include <map>

using namespace std;

const int VAL=100;

vector<int> v[100010];
map<pair<int,int>, int> q;
int trib[100010],rad[100010],sol[100010],v1[100010];
char vaz[100010];

int radacina(int x,int c)
{
    int y=x;
    while(rad[y]!=y) y=rad[y];
    while(x!=y)
    {
        v1[x]=c;
        int aux=rad[x];
        rad[x]=y;
        x=aux;
    }
    return y;
}

void reuneste(int x,int y)
{
    if(v1[x]>v1[y]) swap(x,y);
    int a=radacina(y,v1[x]+v1[y]),b=radacina(x,v1[x]+v1[y]);
    rad[b]=a;
}

int main()
{
    freopen("tribes.in","r",stdin);
    freopen("tribes.out","w",stdout);
    int n,m,k,x,y;
    scanf("%d%d%d",&n,&m,&k);
    for(int i=1;i<=n;i++)
    {
        scanf("%d",&trib[i]);
        rad[i]=i;
        v1[i]=1;
    }
    for(int i=1;i<=m;i++)
    {
        scanf("%d%d",&x,&y);
        v[x].push_back(y);
        q[{x,trib[y]}]=y;
        v[y].push_back(x);
        q[{y,trib[x]}]=x;
    }
    for(int i=1;i<=n;i++)
        for(int j=0;j<v[i].size();j++)
        {
            int vec=v[i][j];
            if(trib[vec]==trib[i]) reuneste(i,vec);
            if(q[{vec,trib[i]}]!=0) reuneste(i,q[{vec,trib[i]}]);
        }
    for(int i=1;i<=n;i++)
        if(v[i].size()<=VAL)
        {
            for(int j=0;j<v[i].size();j++)
                for(int k=0;k<v[i].size();k++)
                    if(v[i][j]!=v[i][k])
                        if(q[{v[i][k],trib[v[i][j]]}]!=0) reuneste(v[i][j],q[{v[i][k],trib[v[i][j]]}]);
        }
    for(int i=1;i<=n;i++)
        if(v[i].size()>VAL)
        {
            for(int j=0;j<v[i].size();j++)
            {
                int vec=v[i][j];
                for(int k=0;v[vec].size();k++)
                    if(v[vec][k]!=i)
                        if(q[{v[vec][k],trib[i]}]!=0) reuneste(i,q[{v[vec][k],trib[i]}]);
            }
        }
    for(int i=1;i<=n;i++)
        if(vaz[rad[i]]==0) {sol[trib[i]]++;vaz[rad[i]]=1;}
    for(int i=1;i<=k;i++)
        printf("%d\n",sol[i]);
    return 0;
}