zoukankan      html  css  js  c++  java
  • HDU1811 Rank of Tetris 并查集+拓扑排序

        该题的难点在于如何去处理掉等号,这里要用到并查集来处理相同的点,不要在输入的时候处理数据,一定要先将数据全部读取完再处理,这是因为相等的点的出现是不可预见的,很可能不能把相等的点的信息全部加到一个点的邻接表上去。

    这里说明两条定理:

    *如果一次入队入度为零的点大于1则说明拓扑排序序列不唯一
    *如果排序的总个数小于给定的个数,则说明存在回路

    这两种情况就对应了不同的错误,前者则是信息不完全,后者则是冲突。当然信息不完全不能够说明它不冲突。

    代码如下:

    #include <stdio.h>
    #include
    <string.h>
    #include
    <stdlib.h>
    #define MAX 10005

    typedef
    struct E
    {
    int sign;
    struct E *next;
    } E;

    struct
    {
    int dg;
    struct E *next;
    }v[MAX];

    int x[MAX], y[MAX], set[MAX], N, M;

    char op[MAX];

    int queue[MAX], front, rear;

    int find( int x )
    {
    return set[x]= x== set[x]? x: find( set[x] );
    }

    void merge( int x, int y )
    {
    int a= find( x ), b= find( y );
    set[a]= b;
    }

    void insert( int x, int y )
    {
    E
    *e= ( E * )malloc( sizeof( E ) );
    e
    -> sign= y;
    e
    -> next= v[x]. next;
    v[x]. next
    = e;
    v[y]. dg
    ++;
    }

    void swap( int &a, int &b )
    {
    int temp= a;
    a
    = b;
    b
    = temp;
    }

    void init( )
    {
    memset( v,
    0, sizeof( v ) );
    for( int i= 0; i< N; ++i )
    {
    set[i]= i;
    }
    front
    = rear= 0;
    }

    int main( )
    {
    while( scanf( "%d %d", &N, &M )!= EOF )
    {
    init( );
    int un= 0, num= N;
    for( int i= 0; i< M; ++i )
    {
    scanf(
    "%d %c %d", &x[i], &op[i], &y[i] );
    if( op[i]== '=' )
    {
    if( find( x[i] )!= find( y[i] ) )
    {
    merge( x[i], y[i] );
    num
    --;
    }
    }
    }
    for( int i= 0; i< M; ++i )
    {
    int a= find( x[i] ), b= find( y[i] );
    if( op[i]== '=' )
    {
    continue;
    }
    if( op[i]== '<' )
    {
    swap( a, b );
    }
    insert( a, b );
    }
    for( int i= 0; i< N; ++i )
    {
    if( v[i].dg== 0&& find( i )== i )
    {
    queue[rear
    ++]= i;
    }
    }
    while( rear!= front )
    {
    if( rear- front> 1 )
    {
    un
    = 1;
    }
    int cur= queue[ front++ ];
    num
    --;
    for( E *p= v[cur]. next; p; p= p-> next )
    {
    if( --v[ p-> sign ]. dg== 0 )
    {
    queue[rear
    ++]= p-> sign;
    }
    }
    }
    if( num> 0 )
    {
    puts(
    "CONFLICT" );
    }
    else if( un== 1 )
    {
    puts(
    "UNCERTAIN" );
    }
    else
    {
    puts(
    "OK" );
    }
    }
    }
  • 相关阅读:
    项目用到的分页功能(保存)
    跟上脚步(微信小程序)
    啊!!!贾克斯。
    Javascript闭包——懂不懂由你,反正我是懂了(作者: FrankFang 来源: 博客园)
    OpenCV4Android 之 OpenCV4Android SDK
    OpenCV4Android 之 Android 开发简介
    (-2147483648 > 0)?
    基于能量水平的无线传感器网络拓扑控制研究
    遍历文件夹及其子孙文件夹中的文件
    目标检测中背景建模方法
  • 原文地址:https://www.cnblogs.com/Lyush/p/2109174.html
Copyright © 2011-2022 走看看