ACM: hdu 1811 Rank of Tetris - 拓扑排序-并查集-离线
hdu 1811 Rank of Tetris
Time Limit:1000MS Memory Limit:32768KB 64bit IO Format:%I64d & %I64u
Description
为了更好的符合那些爱好者的喜好,Lele又想了一个新点子:他将制作一个全球Tetris高手排行榜,定时更新,名堂要比福布斯富豪榜还响。关于如何排名,这个不用说都知道是根据Rating从高到低来排,如果两个人具有相同的Rating,那就按这几个人的RP从高到低来排。
终于,Lele要开始行动了,对N个人进行排名。为了方便起见,每个人都已经被编号,分别从0到N-1,并且编号越大,RP就越高。
同时Lele从狗仔队里取得一些(M个)关于Rating的信息。这些信息可能有三种情况,分别是"A > B","A = B","A < B",分别表示A的Rating高于B,等于B,小于B。
现在Lele并不是让你来帮他制作这个高手榜,他只是想知道,根据这些信息是否能够确定出这个高手榜,是的话就输出"OK"。否则就请你判断出错的原因,到底是因为信息不完全(输出"UNCERTAIN"),还是因为这些信息中包含冲突(输出"CONFLICT")。
注意,如果信息中同时包含冲突且信息不完全,就输出"CONFLICT"。
Input
每组测试第一行包含两个整数N,M(0<=N<=10000,0<=M<=20000),分别表示要排名的人数以及得到的关系数。
接下来有M行,分别表示这些关系
Output
Sample Input
3 3
0 > 1
1 < 2
0 > 2
4 4
1 = 2
1 > 3
2 > 0
0 > 1
3 3
1 > 0
1 > 2
2 < 1
Sample Output
OK
CONFLICT
UNCERTAIN
/*/
中文题: 按照输入把给出的0~n-1排序,如果是'='按照大小排序,如果是'>'||'<'就按照符号排序; 一开始也是被题意给欺骗了,就是这个'=' ,以为'='号的话两边的排序就按照大小,然后WA了一发。 仔细思考之后发现,并不是这样的,例如 0 = 2 虽然按照排序是 2-0这样,但是这两个的值是相等的 也就是说,这两个数要绑定到一起,在去和其他的数进行排序,这下题意就很清晰了:拓扑排序+并查集+离线。 一开始把所有的'='连起来的点全部绑定起来,再用并查集和拓扑排序去排列,看是不是整个队列严格排序。 这个写起来就很快了。 我承认我犯傻,写到排序这里,本来应该去连接两个比较大小的队伍的根节点却忘了,搞得我重新写了几次真是【MDZZ】--真的只能剁手了、、、、 下面有两组AC代码,一组用了STL 一组没用,都是zz惹的祸; AC代码:
/*/
#include"algorithm"
#include"iostream"
#include"cstring"
#include"cstdlib"
#include"string"
#include"cstdio"
#include"vector"
#include"cmath"
#include"queue"
using namespace std;
#define memset(x,y) memset(x,y,sizeof(x))
#define memcpy(x,y) memcpy(x,y,sizeof(x))
#define MX 10005 // 拓扑排序 + 并查集 + STL //因为思路差不多,注释只打在了第一个代码上面。 //////////////////////////////////////////////////////////////////
/////////////////////////////queue////////////////////////////////
////////////////////////////////////////////////////////////////// struct Edge {
int v,nxt;
} E[MX];
int p[MX];
int Head[MX],cnt;
int indegree[MX];
int n,m,st,ed,sum; int find(int x) {
return p[x]==x?x:(p[x]=find(p[x]));
} int union_root(int a,int b) {
a=find(a);
b=find(b);
if(a!=b) {
p[b]=a;
return 1; //返回是否进行了绑定操作
}
return 0;
} void init() {
memset(Head,-1);
memset(E,0);
memset(indegree,0);
for(int i=0; i<=n; i++) {
p[i]=i;
}
cnt=0;
sum=n;
} void edge_add(int st,int ed) {
E[cnt].v=ed;
E[cnt].nxt=Head[st];
Head[st]=cnt++;
} void toposort() { //几乎是模版。
int information=1;
queue<int>Q;
while(!Q.empty())Q.pop();
for(int i=0; i<n; i++) {
if(!indegree[i]&&find(i)==i) //入度为0,且是根节点
Q.push(i);
}
while(!Q.empty()) {
if(Q.size()>1)information=0; //如果出现了多个入度为0的点说明没有严格排序,即信息不全,标记
int a=Q.front();
Q.pop();
sum--;
for(int i=Head[a]; ~i; i=E[i].nxt) {
int v=E[i].v;
indegree[v]--;
if(!indegree[v]) {
Q.push(v);
}
}
}
if(sum>0)printf("CONFLICT\n"); //出现了矛盾[环]就说明错了
else if(!information)printf("UNCERTAIN\n");//信息不全
else printf("OK\n");
} int main() {
char B[MX];
int A[MX],C[MX];
while(~scanf("%d%d",&n,&m)) {
init();
for(int i=0; i<m; i++) {
cin>>A[i]>>B[i]>>C[i];
if(B[i]=='=') {
if(union_root(A[i],C[i])) sum--;//绑定两个值相等的点,如果绑定了联通块数量 --;
}
}
for(int i=0; i<m; i++) {
if(B[i]=='=')continue;//这里要跳过已经绑定了的点
if(B[i]=='>') { //按照符号去排列大小
st=find(A[i]);
ed=find(C[i]);
} else {
st=find(C[i]);
ed=find(A[i]);
}
edge_add(st,ed);
indegree[ed]++;
}
toposort();
}
return 0;
} /////////////////////////////////////////////////////////////
///////////////////// vector + queue ////////////////////////
///////////////////////////////////////////////////////////// struct Edge {
int v,nxt;
} E[MX];
int p[MX];
int indegree[MX];
int n,m,st,ed,sum; vector<int >next_node[MX]; int find(int x) {
return p[x]==x?x:(p[x]=find(p[x]));
} int union_root(int a,int b) {
a=find(a);
b=find(b);
if(a!=b) {
p[b]=a;
return 1;
}
return 0;
} void init(int n) {
memset(E,0);
memset(indegree,0);
for(int i=0; i<n; i++) {
next_node[i].clear();
p[i]=i;
}
sum=n;
} void toposort() {
int information=1;
queue<int>Q;
while(!Q.empty())Q.pop();
for(int i=0; i<n; i++) {
if(!indegree[i]&&find(i)==i)
Q.push(i);
}
while(!Q.empty()) {
if(Q.size()>1)information=0;
int a=Q.front();
Q.pop();
sum--;
for(int i=0;i<next_node[a].size();i++)
{
if(--indegree[next_node[a][i]]==0)
Q.push(next_node[a][i]);
}
}
if(sum>0)printf("CONFLICT\n");
else if(!information)printf("UNCERTAIN\n");
else printf("OK\n");
} int main() {
char B[MX];
int A[MX],C[MX];
while(~scanf("%d%d",&n,&m)) {
init(n);
for(int i=0; i<m; i++) {
cin>>A[i]>>B[i]>>C[i];
if(B[i]=='=') {
if(union_root(A[i],C[i]))sum--;
}
}
for(int i=0; i<m; i++) {
if(B[i]=='=')continue;
if(B[i]=='>') {
st=find(A[i]);
ed=find(C[i]);
} else {
st=find(C[i]);
ed=find(A[i]);
}
next_node[st].push_back(ed);
indegree[ed]++;
}
toposort();
}
return 0;
}
ACM: hdu 1811 Rank of Tetris - 拓扑排序-并查集-离线的更多相关文章
- hdu 1811 Rank of Tetris - 拓扑排序 - 并查集
自从Lele开发了Rating系统,他的Tetris事业更是如虎添翼,不久他遍把这个游戏推向了全球. 为了更好的符合那些爱好者的喜好,Lele又想了一个新点子:他将制作一个全球Tetris高手排行榜, ...
- hdu1811 Rank of Tetris 拓扑排序+并查集
这道题是拓扑排序和并查集的综合运用. 由于排行榜是一种从高到低的排序.所以在拓扑排序的时候,如果有一次加入的入度为零的点数大于1,就有变得不确定了(UNCERTAIN). 由于只有一棵树,当树的数量大 ...
- Rank of Tetris 拓扑排序+并查集
Problem Description 自从Lele开发了Rating系统,他的Tetris事业更是如虎添翼,不久他遍把这个游戏推向了全球. 为了更好的符合那些爱好者的喜好,Lele又想了一个新点子: ...
- hdu 1811 Rank of Tetris (拓扑 & 并查集)
Rank of Tetris Time Limit: 1000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)To ...
- HDU 1811 拓扑排序 并查集
有n个成绩,给出m个分数间的相对大小关系,问是否合法,矛盾,不完全,其中即矛盾即不完全输出矛盾的. 相对大小的关系可以看成是一个指向的条件,如此一来很容易想到拓扑模型进行拓扑排序,每次检查当前入度为0 ...
- HDU 1811 Rank of Tetris(并查集按秩合并+拓扑排序)
Rank of Tetris Time Limit: 1000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others) T ...
- HDU 1811 Rank of Tetris(拓扑排序+并查集)
题目链接: 传送门 Rank of Tetris Time Limit: 1000MS Memory Limit: 32768 K Description 自从Lele开发了Rating系统, ...
- HDU 1811 Rank of Tetris(并查集+拓扑排序 非常经典)
Rank of Tetris Time Limit: 1000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)To ...
- hdu 1811 Rank of Tetris (并查集+拓扑排序)
Rank of Tetris Time Limit: 1000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)To ...
随机推荐
- Android Message Handling Mechanism
转自:http://solarex.github.io/blog/2015/09/22/android-message-handling-mechanism/ Android is a message ...
- Android中Service 使用详解(LocalService + RemoteService)
Service 简介: Service分为本地服务(LocalService)和远程服务(RemoteService): 1.本地服务依附在主进程上而不是独立的进程,这样在一定程度上节约了资源,另外L ...
- 【翻译二十一】java-并发之分拆和合并
Fork/Join This section was updated to reflect features and conventions of the upcoming Java SE 8 rel ...
- poj 1195:Mobile phones(二维线段树,矩阵求和)
Mobile phones Time Limit: 5000MS Memory Limit: 65536K Total Submissions: 14391 Accepted: 6685 De ...
- SVN-简要说明
SVN官方推荐在一个版本库的根目录下先建立trunk.branches.tags这三个文件夹,其中trunk是开发主干,存放日常开发的内容:branches存放各分支的内容,比如为不同客户定制的不同版 ...
- [Linux][VMWare] 学习笔记之安装Linux系统-网络配置
最近开始折腾Linux,在本机装了个VMWare和Centos,装完之后虚拟机里面的OS可以上网,但是使用SecureCRT连接不上虚拟机,开始折腾这个网络. vmware安装好以后,会自动添加两张网 ...
- 第四篇:SOUI资源文件组织
什么是资源? 现代的软件只要有UI,基本上少不了资源. 资源是什么?资源就是在程序运行时提供固定的数据源的文件. 在MFC当道的时代,资源一般就是位图(Bitmap),图标(Icon),光标(Curs ...
- Bag-of-words模型
Bag-of-words模型是信息检索领域常用的文档表示方法.在信息检索中,BOW模型假定对于一个文档,忽略它的单词顺序和语法.句法等要素,将其仅仅看作是若干个词汇的集合,文档中每个单词的出现都是独立 ...
- ubuntu初始化root帐号密码
Ubuntu Kylin 14.04的安装过程中并没有提供设置root密码的过程,取而代之的是自定义的帐号. 如果我们需要使用到root帐号或者root权限,则需要重新设置root帐号的密码. 设置方 ...
- 利用opencv进行相机标定程序
#include "Stafx.h" ; //棋盘上有13个格子,那么角点的数目12 ; ; //图片的总张数 int main(int argc, char** argv) { ...