GYM 101243 F.Vitamins【思维+并查集】
来源:互联网 发布:驾照模拟考试c1软件 编辑:程序博客网 时间:2024/06/05 23:03
题目大意:
现在有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");}
阅读全文
0 0
- GYM 101243 F.Vitamins【思维+并查集】
- Gym 100712F Travelling Salesman(二分+并查集)
- Codeforces 659F Polycarp and Hay【思维+并查集+Bfs】
- GYM 100685 G【并查集】
- Gym 100703J 并查集
- codeforces gym 101142 F(思维)
- Gym 100676F Palindrome(并差集)
- ACDREAM 01F(并查集)
- codeforces 659F (并查集 bfs)
- 【并查集入门专题1】F
- Codeforces Gym 100814C Connecting Graph (并查集, 树链剖分)
- Gym - 100625G Getting Through 计算几何+并查集
- GYM 101128 B.Black Vienna(并查集)
- GYM 100971 A.Treasure Island(dfs+并查集)
- bzoj1015逆向思维+并查集
- Codeforces 755C 【并查集】【思维】
- codeforces-755【C思维、并查集】
- HDU5606 tree 并查集+思维
- Python编程入门到实践:(看书总结9-9)
- 洛谷P1330 封锁阳光大学(BFS, 并查集)
- java和javascript正则表达对比
- linux c动态链接库的使用
- poj2195 Going Home(费用流|KM)
- GYM 101243 F.Vitamins【思维+并查集】
- es6第三版笔记
- 用实例来理解redux
- Echarts3.0入门基础与实战(学习笔记)
- poj 1149 PIGS 最大流 太神奇的建图方式!!!
- SANet:Structure-Aware Network for Visual Tracking 阅读笔记
- Linux网络编程--服务端判断客户端断开的经验方法
- Redhat enterprise 7安装oracle12
- STM32F103x8B PB3、PB4、PA14、PA15引脚作为普通IO口使用