2016-2017 ACM-ICPC, NEERC, Central Subregional Contest F

Vitamins

题意:有3种分别为白色红色白色的药丸,白色药丸最重,其次的红色蓝色最轻,有n个药丸(1-n),m个质量关系的条件,求每个药丸的颜色,如果不能确定输出?

思路:并查集将药丸分成多个集合,m个关系用出度入度描述但不建图,每个集合内药丸的颜色相等,判断每个集合内存不存在出度和入度,如果一个集合内即又出度又有入度,那么一定是红色,这样可以找到所有红色的药丸,只有与红色有关联的药丸才能判断颜色

AC代码:

#include "iostream"
#include "string.h"
#include "stack"
#include "queue"
#include "string"
#include "vector"
#include "set"
#include "map"
#include "algorithm"
#include "stdio.h"
#include "math.h"
#define ll long long
#define bug(x) cout<<x<<" "<<"UUUUU"<<endl;
#define mem(a) memset(a,0,sizeof(a))
using namespace std;
const int N=1e5+100;
int pre[1005],ans[1005];
void Init(int n){
    for(int i=0; i<=n; ++i){
        pre[i]=i;
    }
}
int finds(int x){
    return pre[x]=x==pre[x]?x:finds(pre[x]);
}
void unions(int x, int y){
    int fx=finds(x), fy=finds(y);
    pre[fy]=fx;
}
int n,m,in[1005],out[1005],u[500005],v[500005];
char c[500005];
int main(){
    freopen("input.txt","r",stdin);
    freopen("output.txt","w",stdout);
    cin>>n>>m;
    Init(n);
    for(int i=1; i<=m; ++i){
        cin>>u[i]>>c[i]>>v[i];
        if(c[i]=='>'){
            in[v[i]]++,out[u[i]]++;
        }
        else if(c[i]=='<'){
            in[u[i]]++,out[v[i]]++;
        }
        else{
            unions(v[i],u[i]);
        }
    }
    int o[1005],k=0;mem(o);
    for(int i=1; i<=n; ++i){
        int fi=finds(i);
        if(fi==i){
            o[++k]=i;
        }
    }
    for(int i=1; i<=k; ++i){
        int ff[5];mem(ff);
        for(int j=1; j<=n; ++j){
            if(finds(j)==o[i]){
                if(in[j]) ff[1]=1;
                if(out[j]) ff[2]=1;
            }
            if(ff[1]+ff[2]==2){
                ans[finds(j)]=2;
                break;
            }
        }
    }
    for(int i=1; i<=m; ++i){
        if(ans[finds(u[i])]==2){
            if(c[i]=='>')  ans[finds(v[i])]=1;
            else if(c[i]=='<')  ans[finds(v[i])]=3;
        }
        else if(ans[finds(v[i])]==2){
            if(c[i]=='>')  ans[finds(u[i])]=3;
            else if(c[i]=='<')  ans[finds(u[i])]=1;
        }
    }
    for(int i=1; i<=n; ++i){
        if(ans[finds(i)]==1)cout<<"B";
        else if(ans[finds(i)]==2) cout<<"R";
        else if(ans[finds(i)]==3)cout<<"W";
        else cout<<"?";
    }
    return 0;
}
原文地址:https://www.cnblogs.com/max88888888/p/7123207.html