sgu 122 The book

来源:互联网 发布:sql2000附加数据库金蝶 编辑:程序博客网 时间:2024/04/26 22:34

题目描述:

122. The book

time limit per test: 0.5 sec.
memory limit per test: 4096 KB

There is a group of N (2<=N<=1000) people which are numbered 1 through N, and everyone of them has not less than [ (N+1) / 2 ] friends. A man with number 1 has the book, which others want to read.Write the program which finds a way of transferring the book so that it will visit every man only once, passing from the friend to the friend, and, at last, has come back to the owner.Note: if A is a friend of B then B is a friend of A.

Input

First line of input contains number N. Next N lines contain information about friendships. (i+1)-th line of input contains a list of friends of i-th man.

Output

If there is no solution then your program must output 'No solution'.   Else your program must output exactly N+1 number: this sequence should begin and should come to end by number 1, any two neighbours in it should be friends, and any two elements in it, except for the first and last, should not repeat.

Sample Input

42 31 41 42 3

Sample Output

1 3 4 2 1


极恶心的一道题,居然卡输入。。。。

我是参考《组合数学》 里给的哈密顿圈的求法实现的代码。

首先我们的图满足Ore性质: 对所有不相邻的不同顶点对x和y,有

deg(x)+deg(y)>=n .

所以原图必存在哈密顿回路。


下面给出《组合数学》 里关于哈密顿圈的求法:

1) 从任意一个顶点开始,在他的任意一端邻接一个端点,构造一条越来越长的路径,直到不能构造为止。设该路径为

                                                 L :y1->y2->y3->..........->ym

                                              (在实现中对应函数first() );

2)检查y1和ym 是否邻接。

a) 如果y1和ym 不邻接,转到3);否则,转到b).

b) 如果m==n算法结束,输出路径;否则,转到c)。

c) 找出不在L路径上的顶点z和在路径上的点yk,满足z和yk是邻接的,用下面的路径代替原路径

                        z->yk->yk+1->........->ym->y1->......->yk-1(实现是有second2() )

转回2);

3)找出一个顶点yk(1<k<m) ,满足y1和yk是邻接的,且yk-1和ym也是邻接的,用下面的路径代替原路径

                      y1->y2->.........->yk-1->ym->........yk(实现是由函数third() )

转回2);


这题真心恶心啊,

首先写了dfs版本,毋庸置疑的TLE,然后是PE3,不知道是为什么,知道的大神请告诉我吧。

在然后是各种RE。。。

然后是MLE。。。。

在然后又是TLE。。。

一道题,让我能错的方式全都错了一遍,真心坑啊。。。


最后的输入方式还是参考大牛的意见才AC的,无限感激和膜拜Orz。。。


最后,贴个代码,记录我的不容易啊。。。

#include<iostream>#include<cstring>#include<cstdio>#include<set>#include<algorithm>#include<vector>#include<cstdlib>#define inf 0xfffffff#define CLR(a,b) memset((a),(b),sizeof((a)))#define FOR(a,b) for(int a=1;a<=(b);(a)++)using namespace std;int const nMax = 1100;int const base = 10;typedef int LL;typedef pair<LL,LL> pij;//vector<int> e[nMax];int n;char s[nMax*5];bool vis[nMax];int L[nMax],R[nMax];int he,ta;bool map[nMax][nMax];set<int> Q;void put();void first (){    he=ta=0;    int u=1;    he=ta=1;    vis[u]=true;    L[u]=R[u]=-1;    while(1){        bool ok=false;        int v;       // for(int i=0;i<e[u].size();i++)if(!vis[v=e[u][i]]){       for(v=1;v<=n;v++)if(map[u][v]&&!vis[v]){            //chain[ta++]=v;            ta=v;            R[u]=v;L[v]=u;R[v]=-1;            vis[v]=true;            u=v;            ok=true;            break;        }        if(!ok)break;    }    for(int u=he;u!=-1;u=R[u]){        //for(int j=0;j<e[u].size();j++)if(!vis[e[u][j]]){        for(int j=1;j<=n;j++)if(map[u][j]&&!vis[j]){            Q.insert(j);        }    }   // printf(" Case :first :\n");   // put();    return ;}bool  second1(){    int u=he;    int v=ta;    if(map[u][v]){        R[v]=u;L[u]=v;        return true;    }    return false;}void second2(){    int z=*Q.begin();    Q.erase(Q.begin());    int v;   // for(int i=0;i<e[z].size();i++)if(vis[v=e[z][i]]){    for(v=1;v<=n;v++)if(map[z][v]&&vis[v]){        break;    }    he=z;    L[he]=-1;    ta=L[v];    R[L[v]]=-1;    R[z]=v;    L[v]=z;    vis[z]=true;    //for(int i=0;i<e[z].size();i++)if(!vis[v=e[z][i]])    for(v=1;v<=n;v++)if(map[z][v]&&!vis[v])    Q.insert(v);  //  printf(" Case :second2 :\n");   // put();    return ;}void rever(int v,int t){    for(int i=v;i!=-1;i=L[i]){        swap(R[i],L[i]);    }    R[R[v]]=t;    L[t]=R[v];    R[v]=he;    L[he]=v;    return ;}void third(){    int s=he,t=ta;    for(int v=R[s];v!=t;v=R[v])if(map[s][v]&&map[L[v]][t]){     //   printf("v=%d\n",v);        rever(v,t);ta=v;    //    printf(" Case :third :\n");    //    put();        return ;    }    return ;}void output(){    printf("1");    for(int v=R[1];v!=1;v=R[v])printf(" %d",v);    printf(" 1 \n");    return ;}void put(){    for(int i=he;;i=R[i]){        printf("%d ",i);        if(i==ta)break;    }    puts("");    return ;}void Hamiton(){    first();    while(1){        if(second1()){            if(Q.empty()){                output();                return ;            }else{                second2();            }        }else {            third();        }    //    put();    }    return ;}int main(){    scanf("%d",&n);    gets(s);    char*token;    int x;    FOR(u,n){       // e[u].clear();        gets(s);        //gets(buffer);        token = strtok(s, " ");        while (token != NULL) {            x = atoi(token);            map[u][x] = true;            token = strtok(NULL, " ");        }        /*char *p=s;int l,v;        while(~sscanf(p,"%d%n",&v,&l)){          //  e[u].push_back(v);            map[u][v]=true;            p+=l;        }*/    }    CLR(vis,false);    Q.clear();    Hamiton();    return 0;}



原创粉丝点击