hdu 1811 Rank of Tetris 并查集+拓扑排序,,提高题

Rank of Tetris

Time Limit: 1000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)

Total Submission(s): 5672    Accepted Submission(s): 1616

Problem Description

自从Lele开发了Rating系统,他的Tetris事业更是如虎添翼,不久他遍把这个游戏推向了全球。

为了更好的符合那些爱好者的喜好,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

有时候感觉自己真笨。

上一个人的博客吧。http://972169909-qq-com.iteye.com/blog/1052820

代码:

#include <cstdio>
#include <queue>
#include <cstring>
#define MAX 10100

using namespace std ;

struct Node{
	int to,next;
}edge[2*MAX];

int f[MAX] , head[MAX] ,a[2*MAX],b[2*MAX] , in[MAX];
char ch[2*MAX] ;
bool visited[MAX] ;
void init(int n)
{
	for(int i = 0 ; i <= n ; ++i)
	{
		f[i] = i ;
		head[i] = -1 ;
		visited[i] = false ;
		in[i]=0;
	}
}

int find(int x)
{
	int r=x ;
	while(r != f[r])
	{
		r = f[r] ;
	}
	int temp = x ;
	while(temp != r)
	{
		x = f[temp] ;
		f[temp] = r ;
		temp = x ;
	}
	return r ;
}

int main()
{
	int m , n;
	while(scanf("%d%d",&n,&m) != EOF)
	{
		init(n) ;
		int num = n ;
		for(int i = 0 ; i < m ; ++i)
		{
			scanf("%d %c %d",a+i,ch+i,b+i) ;
			if(ch[i] == '=')
			{
				int fa = find(a[i]),fb = find(b[i]) ;
				if(fa != fb)
				{
					f[fa] = f[fb] ;
					num-- ;
				}
			}
		}
		int index = 0 ;
		bool flag = false ;
		for(int i = 0 ; i < m ; ++i)
		{
			if(ch[i] == '=')
				continue ;
			int fa = find(a[i]) , fb = find(b[i]) ;		//一定要注意这个,每次都是直接更新到父结点上!!
			if(fa == fb)
			{
				flag = true ;
				break ;
			}
			if(ch[i] == '>')
			{
				bool repeat = false ;
				for(int j = head[fa] ; j != -1 ; j = edge[j].next)		//防止重边,下同
				{
					if(edge[j].to == fb)
					{
						repeat = true ;
						break ;
					}
				}
				if(!repeat)
				{
					edge[index].to = fb;		//不是更新当前的边,,而是从更新父结点。
					edge[index].next = head[fa] ;
					head[fa] = index++  ;
					in[fb] ++;
				}
			}
			else if(ch[i] == '<')
			{
				bool repeat = false ;
				for(int j = head[fb] ; j != -1 ; j = edge[j].next)
				{
					if(edge[j].to == fa)
					{
						repeat = true ;
						break ;
					}
				}
				if(!repeat)
				{
					edge[index].to = fa;
					edge[index].next = head[fb];
					head[fb] = index ++ ;
					in[fa]++ ;
				}
			}
		}
		if(flag)
		{
			puts("CONFLICT");
			continue ;
		}
		flag = false ;
		queue<int> que ;
		for(int i = 0 ; i < n ; ++i)
		{
			if(in[i] == 0 && i == find(i))
			{
				que.push(i) ;
			}
		}
		while(!que.empty())
		{
			if(que.size()>1)
			{
				flag = true ;
			}
			num-- ;
			int j = que.front() ;
			que.pop() ;
			visited[j] = true ;
			for(int k = head[j] ; k != -1 ; k = edge[k].next)
			{
				in[edge[k].to]--;
				if(!visited[edge[k].to] && in[edge[k].to]==0)
				{
					que.push(edge[k].to) ;
				}
			}
		}
		if(num>0)
		{
			puts("CONFLICT") ;
		}
		else if(flag)
		{
			puts("UNCERTAIN") ;
		}
		else
		{
			puts("OK") ;
		}
	}
	return 0 ;
}

与君共勉

时间: 2024-10-23 18:52:17

hdu 1811 Rank of Tetris 并查集+拓扑排序,,提高题的相关文章

hdu 1811 Rank of Tetris (并查集+拓扑排序)

Rank of Tetris Time Limit: 1000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total Submission(s): 5415    Accepted Submission(s): 1514 Problem Description 自从Lele开发了Rating系统,他的Tetris事业更是如虎添翼,不久他遍把这个游戏推向了全球. 为了更好的符合那些爱好者的喜好,Lele又想了

hdu1811 Rank of Tetris 并查集+拓扑排序

1 #include <stdio.h> 2 #include <string.h> 3 #include <vector> 4 #include <queue> 5 using namespace std; 6 struct node//边 7 { 8 int a, b;//顶点 9 char ch;//运算符 10 }c[10005]; 11 vector<int>map[10005];//map数组存贮邻接表 (大佬都是这么开数组的) 12

hdu 1811Rank of Tetris (并查集 + 拓扑排序)

1 /* 2 题意:这些信息可能有三种情况,分别是"A > B","A = B","A < B",分别表示A的Rating高于B,等于B,小于B. 3 4 现在Lele并不是让你来帮他制作这个高手榜,他只是想知道,根据这些信息是否能够确定出这个高手榜,是的话就输出"OK". 5 否则就请你判断出错的原因,到底是因为信息不完全(输出"UNCERTAIN"),还是因为这些信息中包含冲突(输出&quo

hdu--1811--并查集&amp;&amp;拓扑排序&lt;好题&gt;

做了这题 绝逼 累啊.. mle -- re<stack overflow>--tle--wa---ac 经过这么5步 终于AC了 这题 我觉得可以让你更好地来 理解 拓扑排序的一些细节问题 首先 这题 为什么要用到并查集呢? 因为 会有 A = B这种情况的出现 然后可能再来个 B =C A = D....那么我们就需要将它们全部表示成一个点 那么就是都用一个根结点来表示 然后 这边 是要判断 能不能根据给出的条件 形成一个排列 那么就是个 拓扑问题 根据 > <情况来判断 我觉

HDU1811Rank of Tetris(并查集+拓扑排序)

Rank of Tetris Time Limit: 1000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total Submission(s): 5683    Accepted Submission(s): 1622 Problem Description 自从Lele开发了Rating系统,他的Tetris事业更是如虎添翼,不久他遍把这个游戏推向了全球. 为了更好的符合那些爱好者的喜好,Lele又想

【HDU】5222 Exploration(并查集+拓扑排序)

对于无向边使用并查集合并成一个集合,对于有向边使用判断是否存在环 唯一无语的地方就是看输入是百万级的,加个输入挂跑9s,不加挂跑了5s #include<cstdio> #include<cstring> #include<vector> #include<algorithm> using namespace std; #pragma comment(linker, "/STACK:102400000,102400000") const

HDU 1811:Rank of Tetris(并查集+拓扑排序)

http://acm.hdu.edu.cn/showproblem.php?pid=1811 Rank of Tetris Problem Description 自从Lele开发了Rating系统,他的Tetris事业更是如虎添翼,不久他遍把这个游戏推向了全球.为了更好的符合那些爱好者的喜好,Lele又想了一个新点子:他将制作一个全球Tetris高手排行榜,定时更新,名堂要比福布斯富豪榜还响.关于如何排名,这个不用说都知道是根据Rating从高到低来排,如果两个人具有相同的Rating,那就按

hdu 1811 Rank of Tetris (拓扑排序+并查集)

Rank of Tetris Time Limit: 1000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)Total Submission(s): 4931 Accepted Submission(s): 1359 Problem Description自从Lele开发了Rating系统,他的Tetris事业更是如虎添翼,不久他遍把这个游戏推向了全球. 为了更好的符合那些爱好者的喜好,Lele又想了一个新点子:他

hdu 1811 Rank of Tetris 【并查集+拓扑排序】

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1811 分析: 很明显是道拓扑排序的题,有一点就是处理实力相等的问题: 可以用并查集把实力相等的组成一个集合. 说一下拓扑排序的性质: 1.如果入度为0的点大于1,则排序不唯一 2.如果排序的总数小于给定的数,则存在环路 献上代码: #include<stdio.h> #include<string.h> #include<algorithm> #include<ios