欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

GYM 101243 F.Vitamins【思维+并查集】

程序员文章站 2022-06-04 16:16:38
...

GYM 101243 F.Vitamins【思维+并查集】


题目大意:

现在有N个物品,已知有M个信息,表示两个物品谁更重,或者一样重,现在有三种重量,WRB,从大到小递减,问我们能够确定哪些物品的重量,如果不确定的,输出?否则输出其重量的等级(W/R/B);

保证没有环,也没有非法情况


思路:


如果能够确定一个物品的重量,那么这个物品一定处于一条长度为2的链子上,那么我们可以O(n)枚举个点,判断其是否在这个长度为2的链子的中间点上即可。

如果在的话,对应将这三个点都标上颜色,维护下去即可。

问题的小难点在于等号情况,其实这里我们只要将所有等号的部分都用并查集搞在一起即可,每一次加边我们都用并查集的祖先节点去代替就行。


Ac代码:


#include <bits/stdc++.h>
typedef long long int LL;
using namespace std;
const int MOD = 1e9+7;
void fre()
{
    freopen("INPUT.TXT","r",stdin);
    freopen("OUTPUT.TXT","w",stdout);
}
int ok;
char ans[1500];
int vis[1500];
int f[1500];
vector<int>mp[1500],re[1500];
int uu[1500*1500],vv[1500*1500],opp[1500*1500];
int find(int u)
{
    int r=u;
    while(r!=f[r])
    {
        r=f[r];
    }
    int i=u,j=r;
    while(i!=j)
    {
        j=f[i];
        f[i]=r;
        i=j;
    }
    return r;
}
int merge(int u,int v)
{
    int uu=find(u);
    int vv=find(v);
    if(uu!=vv)
    {
        f[uu]=vv;
    }
}
int main()
{
    fre();
    int n,m;
    scanf("%d%d",&n,&m);
    for(int i=1; i<=n; i++)f[i]=i;
    for(int i=1; i<=n; i++)mp[i].clear(),re[i].clear();
    for(int i=1; i<=m; i++)
    {
        char a[1500];
        scanf("%s",a);
        int len=strlen(a);
        int u=0,v=0,flag=0,op;
        for(int j=0; j<len; j++)
        {
            if(a[j]>='0'&&a[j]<='9'&&flag==0)
            {
                u=u*10+(a[j]-'0');
            }
            else if(a[j]>='0'&&a[j]<='9'&&flag==1)
            {
                v=v*10+(a[j]-'0');
            }
            else
            {
                if(a[j]=='>')op=1;
                if(a[j]=='<')op=2;
                if(a[j]=='=')op=3;
                flag++;
            }
        }
        if(op==3)
        {
            merge(u,v);
        }
        uu[i]=u;
        vv[i]=v;
        opp[i]=op;
    }
    for(int i=1;i<=m;i++)
    {
        int u=uu[i],v=vv[i],op=opp[i];
        if(opp[i]==3)continue;
        if(op==1)
        {
            u=find(u),v=find(v);
            mp[u].push_back(v);
            re[v].push_back(u);
        }
        if(op==2)
        {
            u=find(u),v=find(v);
            mp[v].push_back(u);
            re[u].push_back(v);
        }
    }
    memset(ans,'?',sizeof(ans));
    for(int i=1; i<=n; i++)
    {
        if(mp[i].size()>0&&re[i].size()>0)
        {
            ans[i]='R';
            for(int j=0; j<mp[i].size(); j++)
            {
                int v=mp[i][j];
                ans[v]='B';
            }
            for(int j=0; j<re[i].size(); j++)
            {
                int v=re[i][j];
                ans[v]='W';
            }
        }
    }
    for(int i=1; i<=n; i++)
    {
        if(f[i]==i)
        {
            for(int j=1; j<=n; j++)
            {
                if(i==j)continue;
                else if(find(j)==find(i))
                {
                    ans[j]=ans[i];
                }
            }
        }
    }
    for(int i=1; i<=n; i++)
    {
        printf("%c",ans[i]);
    }
    printf("\n");
}