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 ...
随机推荐
- OCJP(1Z0-851) 模拟题分析(八)over
Exam : 1Z0-851 Java Standard Edition 6 Programmer Certified Professional Exam 以下分析全都是我自己分析或者参考网上的,定有 ...
- sublime text 全局搜索
Ctrl+Shift+F Mac下是commadn+Shift+F 在下面Find中填入需要搜索的关键字 点击find
- android 运行时出现The connection to adb is down, and a severe error has occured.(转)
点击项目run,报了这样的错,前几天都好好的: [2013-09-14 15:27:13 - QualityPicture_Client1.3.1.9.7.1] ----------------- ...
- [JavaCore] 取得类的字节码、取得类的装载器
三种方式取得类的字节码: 1. 类名.class BranchInfoService.class 2. 对象名.getClass() branchInfoService.getClass() 3. C ...
- The Basics of 3D Printing in 2015 - from someone with 16 WHOLE HOURS' experience
全文转载自 Scott Hanselman的博文. I bought a 3D printer on Friday, specifically a Printrbot Simple Metal fro ...
- linux系统定时任务
crontab常用的几个命令如下 sudo crontab -l #显示所有的定时任务 sudo crontab -e #编辑任务 sudo crontab -r #删除所有的任务 编辑任务时的书写方 ...
- Eclipse的详细安装步骤
第一种:这个方法是在线安装的 第二种:下载完整免安装包 首先打开网址:http://www.eclipse.org/ 然后在这里我就选择64位的安装,就以安装安卓开发的举例: 然后下载即可:
- 智能车学习(七)——按键矩阵的实现
一.原理说明 就是按键矩阵代码书写的一个说明,就是讲K5到K7先输出高电平,而K1和K4则调成上拉输入,如果检测到K1到K4有一个变为0,说明有按键按下去,立刻进行转换,是的K1到K4设置为输出高电平 ...
- java 日历代码实现
System.out.println("请输入日期(按照格式:2030-3-10):"); //在控制台输入 //String str="2016-9-26"; ...
- jdk1.7和Android Studio2.0的问题
提示的错误 Error:Execution failed for task ':app:transformClassesWithDexForDebug'.> com.android.build. ...