hdu1811Rank of Tetris--结题报告

题意很明了,但是我不知道是不是有人和我一样,一开始在纠结一个愚蠢的问题:

0 > 1, 0 > 2; 应该是能确定的,因为0 大于1,0大于2,那么1和2又可以按人品排名,应该是OK呀。。。。好吧,实在是智商捉急..答案是不确定的,因为按人品排名,我们只能是在 1 = 2 的情况下,没有说明 = ,那么怎么可以认为等级一样呢?

下面开始详细题解分析:

最开始做的时候,是在图论500题上看到的,分类是 拓扑+并查集,两个基本知识点都不难,我就上了。。谁知道。。。首先要想到,然后就是细心,我的处理方式是这样的:

1,先把等级一样的 ,也就是有‘=’ 的两个点并在一个并查集里面,也就是说,等级相同的,我们就看做一个点,用祖先root表示,其他的先不处理,用数组 a[i]  ch[i] b[i] 保存起来

2,然后我们再for(0 ~ M) 条边,遍历一次,用数组邻接表建有向图,记录入度,同时记录新图当中的点数node_num(这里等级相同的在一个集合里面看做一个点root)

3,然后就开始 拓扑排序,那么这里需要记录的情况比较杂乱,要细心

4,首先将入度为 0 的点入队,(这里用队列+邻接表来拓扑也是第一次,每次出队一个 u,我们对其进行拓扑,记录拓扑的点数 topo_num ++;然后用邻接表遍历邻接点  v--也就相当于删边操作,遍历过程中,邻接点 v 入度--,如果减完之后为0,那么入队,同时,记录一个节点删除会带来的入度为0的点数 num ++,如果num > 1,那么这里排名就不确定啦),那么上面说的就是用队列+邻接表处理拓扑排序的一般方法,我们在这个题目中需要添加一点点东西,在对于出队的点,用邻接表遍历邻接点的时候,我们就把u
和 v 并在一个并查集里面,这里是为了后面判断拓扑完后,所有的点是不是在一个集合里面

OK 基本的方法就在上面啦,那么这里主要情况比较复杂就在于什么时候我们是冲突,什么时候不确定,什么时候是OK,这里我这样判断的:

OK 上马:

#include <iostream>
#include <cstdio>
#include <queue>
#include <cstring>

using namespace std;

#define MAX 10005

int N,M;

int degree[MAX];//记录入度
int father[MAX];//并查集

struct Edge
{
    int to,next;
} edge[MAX*2];
int head[MAX],tol;

void add(int u,int v)
{
    edge[tol].to = v;
    edge[tol].next = head[u];
    head[u] = tol++;
}

int find(int x)
{
    if(x != father[x]){
        father[x] = find(father[x]);
    }
    return father[x];
}

char ch[MAX];
int a[MAX],b[MAX];
void initMap()
{
    for(int i = 0; i < N; i ++) father[i] = i;
    for(int i = 0; i < M; i ++)
    {
        scanf("%d %c %d",&a[i],&ch[i],&b[i]);
        if(ch[i] == '=') //同一级别的放在一个集合中
        {
            int x = find(a[i]);
            int y = find(b[i]);
            father[x] = find(y);
        }
    }
    //第二步来建图
    tol = 0;
    memset(head,-1,sizeof(head));
    memset(degree,0,sizeof(degree));
    for(int i = 0; i < M; i ++)
    {
        int x = find(a[i]),y = find(b[i]);
        if(ch[i] == '>'){
            add(x,y); degree[y] ++;
        }
        else if(ch[i] == '<'){
            add(y,x); degree[x] ++;
        }
    }
}

int topo()
{
    int node_num = 0;//新建图的点数
    queue<int>q;
    for(int i = 0; i < N; i ++)
    {
        if(father[i] == i){
            node_num ++;
            if(degree[i] == 0) q.push(i);
        }
    }

    int topo_num = 0;//经过topo的点数
    bool unsure = false;//是不是出现不确定情况
    while(!q.empty())
    {
        int num = 0;//这一轮过程中产生入度为0的点数
        int u = q.front();
        q.pop();
        topo_num++;
        for(int i = head[u]; i != -1; i = edge[i].next)
        {
            int v = edge[i].to;
            degree[v] --;
            father[find(u)] = find(v); //并入

            if(!degree[v]){
                num++; q.push(v);
            }
        }
        if(num > 1) unsure = true;//就已经说明不确定啦
    }

    bool inAset = true;
    for(int i = 0; i < N-1; i ++){
        if(find(i) != find(i+1)){ //两两之间在一个集合
            inAset = false;
        }
    }//下面的判断结合上图的分析
    if(topo_num != node_num) return 1;
    else{
        if(inAset){
            if(unsure) return 2;
            else return 0;
        }else return 2;
    }
}

int main()
{
    while(cin >> N >> M)
    {
        initMap();
        int ans = topo();
        if(ans == 1) cout<<"CONFLICT"<<endl;
        else if(ans == 2) cout << "UNCERTAIN" <<endl;
        else cout << "OK" <<endl;
    }
    return 0;
}

OK 个人愚昧观点,欢迎指正与讨论

hdu1811Rank of Tetris--结题报告

时间: 2024-08-03 09:01:13

hdu1811Rank of Tetris--结题报告的相关文章

初步了解--状态压缩dp---poj1185炮兵布阵结题报告

好吧,借助poj1185炮兵布阵这题,仔仔细细的了解了一下状态压缩动态规划 首先,借助题目,我们来看看状态压缩是个虾米东西..Ok follow me 一,所谓状态压缩 根据题意,我们得在长度为M 的地图上放置一些大炮(后面简称"放炮",应该不会被和谐吧),那么,首先不考虑山地,我们得把所有的放置方法都找出来,并且注意,这里只对于一行且长度为M(好吧,你可能要问考虑一行,左右互相隔2,互相不在攻击范围,那么上下呢?这里先不急,一步步来) 1,找出所有放炮的方法 假设长度为7,那么看下图

关于填报《国家自然科学基金资助项目结题报告》的补充说明

项目负责人在线提交<结题报告>后,只需打印系统生成的PDF版本,签字后交依托单位. 原<结题报告>撰写提纲与说明中第三项,要求随纸质结题报告提供的附件材料,在电子化后上传即可,无需再随结题报告报送纸质附件材料. <结题报告>中的摘要包括项目摘要和结题摘要两部分,其中项目摘要的内容从计划书中自动生成,结题摘要须以深入浅出的语言简明扼要地概括出项目的精华,如背景.方向.主要内容.重要结果.关键数据及其科学意义等.

poj1185炮兵布阵结题报告--初步了解--状态压缩dp

好吧,借助poj1185炮兵布阵这题,仔仔细细的了解了一下状态压缩动态规划 首先,借助题目,我们来看看状态压缩是个虾米东西..Ok follow me 一,所谓状态压缩 根据题意,我们得在长度为M 的地图上放置一些大炮(后面简称"放炮",应该不会被和谐吧),那么,首先不考虑山地,我们得把所有的放置方法都找出来,并且注意,这里只对于一行且长度为M(好吧,你可能要问考虑一行,左右互相隔2,互相不在攻击范围,那么上下呢?这里先不急,一步步来) 1,找出所有放炮的方法 假设长度为7,那么看下图

《基于Cortex-M4的ucOS-III的应用》课程设计 结题报告

<基于Cortex-M4的ucOS-III的应用>课程设计 结题报告 小组成员姓名:20155211 解雪莹 20155217 杨笛 20155227 辜彦霖 指导教师:娄嘉鹏 一.设计方案及可行性分析 题目要求:ucOS-III的移植:设计三个小实验:单一任务.多任务.并发任务. 1.设计方案 首先运行老师给的范例代码熟悉开发软件和开发板的使用:收集资料简单了解UCOSIII的基本概念,然后进行UCOSIII移植(移植到STM32f407开发板):移植成功后开始进行UCOSIII实例编程(实

20155211课程设计个人结题报告

20155211课程设计个人结题报告 个人贡献 参与课设题目讨论及完成全过程 辅助调试代码 资料收集 撰写小组结题报告 实践过程中的问题及解决: 编译之后出现如下错误:..\OBJ\HZ.axf: error: L6050U: The code size of this image (47788 bytes) exceeds the maximum allowed for this version of the linker. 出现错误的原因是:没有完全破解. 解决办法是:按照D:\实验箱资料2

Codeforces 524 结题报告

打的很快乐的一次比赛hiahiahia, 才A掉4题rating就涨了100+ 距离比赛\(3\)天了, 由于博主实在太颓, 又补掉了\(E\)题, 到现在才发解题报告 A. 语法题, 读入输出就行了 #include<cstdio> #include<algorithm> #include<iostream> #define rd read() #define ll long long using namespace std; int read() { int X =

有向图强连通分支的Tarjan算法讲解 + HDU 1269 连通图 Tarjan 结题报告

题目很简单就拿着这道题简单说说 有向图强连通分支的Tarjan算法 有向图强连通分支的Tarjan算法伪代码如下:void Tarjan(u) {dfn[u]=low[u]=++index//进行DFS,每发现一个新的点就对这个点打上时间戳,所以先找到的点时间戳越早,dfn[U]表示最早发现u的时间,low[u]表示u能到达的最早的时间戳.stack.push(u)//将U压入栈中for each (u, v) in E {if (v is not visted)//如果V点没有经历过DFS,则

浙江省第6届程序设计竞赛结题报告汇总 zoj3202-3212

zoj 3202 Second-price Auction 水题,不解释了,直接贴代码 #include<cstdio> #include<cstring> #include<iostream> #include<algorithm> using namespace std; struct node{ int x; int y; }; struct node number[105]; int cmp(struct node a,struct node b){

结题报告——2018级2016第二学期第三周作业9.24

题目一:[NOIP2002P]过河卒 描述 如图,A 点有一个过河卒,需要走到目标 B   点.卒行走规则:可以向下.或者向右.同时在棋盘上的任一点有一个对方的马(如上图的C点),该马所在的点和所有跳跃一步可达的点称为对方马的控制点.例 如上图 C  点上的马可以控制 9 个点(图中的P1,P2 … P8 和 C).卒不能通过对方马的控制点. 棋盘用坐标表示,A 点(0,0).B 点(n,m)(n,m 为不超过 20  的整数,并由键盘输入),同样马的位置坐标是需要给出的(约定: C<>A,同

结题报告——2018级2016第二学期第五周作业9.24

F:[NOIP2008P]排座椅 描述 上课的时候总会有一些同学和前后左右的人交头接耳,这是令小学班主任十分头疼的一件事情.不过,班主任小雪发现了一些有趣的现象,当同学们的座次确定下来 之后,只有有限的D对同学上课时会交头接耳.同学们在教室中坐成了M行N列,坐在第i行第j列的同学的位置是(i,j),为了方便同学们进出,在教室中设 置了K条横向的通道,L条纵向的通道.于是,聪明的小雪想到了一个办法,或许可以减少上课时学生交头接耳的问题:她打算重新摆放桌椅,改变同学们桌椅间通 道的位置,因为如果一条