2016-2017 ACM-ICPC, NEERC, Central Subregional Contest F
题意:有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; }