HDU1811 并查集+拓扑排序

题目大意:

判断是否能根据给定的规则将这一串数字准确排序出来

我们用小的数指向大的数

对于相等的情况下,将二者合并到同一个并查集中,最后抽象出来的图上面的每一个点都应该代表并查集的标号

  1 #include <cstdio>
  2 #include <cstring>
  3 #include <stack>
  4 #include <iostream>
  5 using namespace std;
  6
  7 #define N 10005
  8 char s[N<<1][3];
  9 int fa[N] , first[N] , in[N] , k , cnt;//fa[i]保存的是i点处于的并查集号,cnt记录最后剩下的并查集数
 10 bool vis[N];//判断对应下标的集合是否会进入最后生成的图中
 11 struct Edge{
 12     int y,next;
 13 }e[N<<1];
 14
 15 void add_edge(int x,int y)
 16 {
 17     in[y]++;
 18     e[k].y = y , e[k].next=first[x];
 19     first[x] = k++;
 20 }
 21
 22 void init(int n)
 23 {
 24
 25     k=0;
 26     memset(first , -1 , sizeof(first));
 27     memset(in,0,sizeof(in));
 28     for(int i=0;i<n;i++)
 29         fa[i] = i , vis[i] = true;
 30 }
 31
 32 int find_fa(int x)
 33 {
 34     while(x!=fa[x])
 35         x=fa[x];
 36     return x;
 37 }
 38
 39 void Union(int a , int b)
 40 {
 41     int fa1_set = find_fa(a);
 42     int fa2_set = find_fa(b);
 43     if(fa1_set != fa2_set)
 44     {
 45         fa[fa2_set] = fa1_set , cnt--;
 46         vis[fa2_set] = false; //fa2_set集合被合并,所以最后不会进入图中,所以将其舍去
 47     }
 48 }
 49
 50 int tuopu(int n)
 51 {
 52     stack<int> s;
 53     for(int i = 0 ; i<n ; i++){
 54         if(vis[i] && !in[i]) s.push(i);
 55     }
 56     int flag = 1;
 57     for(int i=0 ; i<cnt ; i++){
 58         if(s.empty()) return -1;
 59         if(s.size() > 1) flag = 0;
 60         int u = s.top();
 61         s.pop();
 62         for(int j=first[u] ; j!=-1 ; j=e[j].next){
 63             int v = e[j].y;
 64             in[v]--;
 65             if(!in[v]){
 66                 s.push(v);
 67             }
 68         }
 69     }
 70     if(!flag) return 0;
 71     return 1;
 72 }
 73
 74 int main()
 75 {
 76    // freopen("a.in" , "rb" ,stdin);
 77     int n , m , a[N] , b[N];
 78     while(scanf("%d%d",&n,&m)!=EOF)
 79     {
 80         init(n);
 81         cnt = n;
 82
 83         for(int i=0;i<m;i++){
 84             scanf("%d%s%d",&a[i],s[i],&b[i]);
 85             if(s[i][0] == ‘=‘){
 86                 Union(a[i],b[i]);
 87             }
 88         }
 89         //cout<<"cnt: "<<cnt<<endl;
 90         for(int i = 0 ; i<m ; i++){
 91             int fa1 = find_fa(a[i]);
 92             int fa2 = find_fa(b[i]);
 93             if(s[i][0] == ‘<‘){
 94                 add_edge(fa1 , fa2);
 95             }
 96             else if(s[i][0] == ‘>‘){
 97                 add_edge(fa2 , fa1);
 98             }
 99         }
100         int flag = tuopu(n);
101         if(flag == 1) puts("OK");
102         if(flag == -1) puts("CONFLICT");
103         if(flag == 0) puts("UNCERTAIN");
104     }
105     return 0;
106 }
时间: 2024-10-29 19:12:31

HDU1811 并查集+拓扑排序的相关文章

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 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....那么我们就需要将它们全部表示成一个点 那么就是都用一个根结点来表示 然后 这边 是要判断 能不能根据给出的条件 形成一个排列 那么就是个 拓扑问题 根据 > <情况来判断 我觉

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

POJ 3660Cow Contest(并查集+拓扑排序)

Cow Contest Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 7567   Accepted: 4206 Description N (1 ≤ N ≤ 100) cows, conveniently numbered 1..N, are participating in a programming contest. As we all know, some cows code better than others

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

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

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

hdu1811 并查集+拓扑序

题意:现在有一个排名系统,有一系列信息,分别是 > < = 的比较,而如果最终相等,就会将这些相等的按照序号从小到大排,问给出的信息是否可以确定完整的排序. 由于如果很多点相等,他们肯定能够确定名次,那么我们只要让他们共同拥有与其他点的大小关系就行了.所以就用到了并查集,将相等的点加入并查集,再对并查集排拓扑序,如果能够排出唯一的拓扑序,那么在每个并查集内部也能够有唯一的顺序. 1 #include<stdio.h> 2 #include<string.h> 3 #in

HDU 5222 ——Exploration——————【并查集+拓扑排序判有向环】

Exploration Time Limit: 30000/15000 MS (Java/Others)    Memory Limit: 131072/131072 K (Java/Others)Total Submission(s): 194    Accepted Submission(s): 63 Problem Description Miceren likes exploration and he found a huge labyrinth underground! This la