【HDU1272】小希的迷宫解题报告,数据+思路+代码

来源:互联网 发布:ubuntu启动黑屏 编辑:程序博客网 时间:2024/06/05 16:13
#include <cstdio>#include <cstdlib>#include <cstring>#include <iostream>#define INPUTusing namespace std;/*    Problem : HDU1272 - 小希的迷宫    State   :    54213202012-02-26 23:40:14Accepted127262MS1636K3853 BG++c0de4fun    Begin Time:26th/2/2012 9:30 p.m;    End Time:26th/2/2012 11:43 p.m    Cost Time: 2 hrs 13 mins;    测试数据:1 4 1 2 2 12 12 13 12 15 15 11 11 3 3 2 4 5 5 9 5 6 6 7 6 8 9 100 01 2 1 3 1 4 2 8 8 9 3 5 5 10 10 12 4 6 6 11 4 70 01 2 3 1 4 1 8 2 8 9 5 3 5 10 10 12 6 4 6 11 4 70 01 4 2 1 2 12 12 13 15 12 15 11 11 3 2 3 4 5 5 9 5 6 6 7 6 8 9 100 06 8  5 3  5 2  6 45 6  0 08 1  7 3  6 2  8 9  7 57 4  7 8  7 6  0 03 8  6 8  6 45 3  5 6  5 2  0 01 2 3 4 0 01 2 0 0-1 -1    Output:NoYesYesNoYesYesNoNoYes    思路:    考察并查集。    每增添一个元素,都要压缩路径,将其parent压缩到顶点。    注意,压缩路径不能采用递归的方式,否则会Exceeded。    压缩路径用while的方式。    每读入一对i,j时有三种情况:    (1)i存在,j不存在     这时候j是新增加的元素     nodes[j].parent = findSet(nodes[i]);     就可以,顺便把nodes[i]的parent更新,并且     counts++,增加统计数据,还要统计Rank.     nodes[nodes[j].parent].rank++;     每个“代表”的Rank就是其集合中的元素数目,会有用的     (2)j存在,i不存在     跟(1)一样,只不过是     nodes[i].parent = findSet(nodes[j]);     counts++;     nodes[nodes[i].parent].rank++;    (3)j存在,i存在     这不太好办     首先判断nodes[j].parent 是否等于 nodes[i].parent     如果是的话,那么fail = true;     如果不是的话     调用Union,Union分别找到j,i的parent     然后Linked双方的Parent,Parent的Rank较大一方成为     新集合的“代表”,较大一方的Rank更新,同时head指向     较大一方     (4)i,j都不存在     这里我们默认j的parent = i,     【但是没有调用findSet!!!!】     所以 head = i!!     ——————————————————————————     需要注意的是,每次调用findSet的时候,需要返回     压缩路径之后的“代表”的下标。以便判断两个已有集合代表     是否相同,同时,还要更新head指针,使其指向该代表。     以便通过代表的Rank和总的元素个数count判断是否只存在     一个集合,如果存在两个集合,那么就Fail = true;     注意,i,j都不存在的时候head = i 否则 1 2 0 0会输出No     ———————————————————————————     结果的判断     只要判断目前head指向的代表的Rank 是否小于 count就可以判断出来     fail,如果小于,那么fail = true;     还有要注意的是fail在i存在,j存在的每次findSet之后也会判断一次     if(fail) print No     else print Yes     Have fun,c0de4fun.*/const int MAX_SIZE = 100010;struct node{    int parent;    int val;    int rank;};node nodes[MAX_SIZE];int allRank = 0;//bool Unioned = false;bool fail = false;int head = 0;void Link(int x,int y){    if(nodes[x].rank > nodes[y].rank)    {        nodes[y].parent = x;        nodes[x].rank = nodes[x].rank + nodes[y].rank;        allRank = nodes[x].rank;        head = x;    }    else    {        nodes[x].parent = y;        nodes[y].rank = nodes[y].rank + nodes[x].rank;        allRank = nodes[y].rank;        head = y;    }}int findSet(node* n){    node tmp;    tmp = *n;    while(tmp.val != tmp.parent)    {        tmp = nodes[tmp.parent];    }    n->parent = tmp.val;    head = tmp.val;    return tmp.val;}void Union(node *i,node *j){ //   Unioned = true;    Link(findSet(i),findSet(j));}int main(int argc,char* argv[]){    int i,j,count = 0;#ifdef INPUT    freopen("b:\\acm\\hdu1272\\input.txt","r",stdin);#endif    while(scanf("%d%d",&i,&j)!= EOF)    {        if( i != - 1 && j != -1)        {            if( i != 0 && j != 0 )            {                //Judge if i already existed.                if(nodes[i].val == 0)                {                    //Not Existed.                    //makeSet(nodes[i])                    nodes[i].parent = i;                    nodes[i].val = i;                    nodes[i].rank = 1;                    count++;                    if(nodes[j].val == 0)                    {                        nodes[j].parent = i;                        nodes[j].val = j;                        nodes[i].rank++;                        head = i;                        count++;                    }                    else                    {                        //node[i].parents = j!                     //  nodes[i].parent = findSet(&node[j]);                       nodes[i].parent = findSet(&nodes[j]);                       nodes[i].val = i;                       nodes[nodes[i].parent].rank++;                    }                }                else //Already Existed                {                 //   nodes[j].parent = i;                    if(nodes[j].val != 0)                    { // To see if nodes[j] existed                        //Yes                        nodes[j].val = j;                       // nodes[j].parent = i;                          findSet(&nodes[j]);                        if (nodes[j].parent == nodes[i].parent)                            fail = true;                        else                            Union(&nodes[j],&nodes[i]);                    }                    else                    {  //No                        nodes[j].parent = i;                        nodes[j].val = j;                        findSet(&nodes[j]);                        nodes[nodes[j].parent].rank++;                        count++;                    }                }            }            else            {            /*  if(Unioned)                {                    if(allRank < count)                        fail = true;                } */             //head没判断明白!                if(nodes[head].rank < count)                    fail = true;                if(fail)                   printf("No\n");                else                   printf("Yes\n");                ////Judge now¡ü                fail = false;                allRank = 0;                count = 0;                Unioned = false;                head = 0;                memset(nodes,0,sizeof(node)*MAX_SIZE);            }        }    }    return 0;}

原创粉丝点击