zoukankan      html  css  js  c++  java
  • sgu 122. The book 满足ore性质的汉密尔顿回路 难度:2

    122. The book

    time limit per test: 0.25 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

    4
    2 3
    1 4
    1 4
    2 3
    

    Sample Output

    1 3 4 2 1

    1.找到一条不能延伸的路径,此时设左边为st,右边为ed,那么一定满足的性质是,st和ed所能到达的所有点都在这条路上,又由于这个图的性质,两点度数加和一定大于n+1,
    根据鸽巢原理,总能找到一个点j,使得j连接ed,nxt[j]连接st,这时候删除j->nxt[j],得到一个环
    2.找到一个在环外的点,拆环并且延伸路径
    重复这两步直到形成长度为n的环

    #include <cstdio>
    #include <cstring>
    using namespace std;
    const int maxn=1001;
    int n;
    bool vis[maxn],use[maxn];
    int  G[maxn][maxn],len[maxn],pre[maxn],nxt[maxn],st,ed;
    int predfs(int cnt){
        vis[st]=true;
        for(int i=0;i<len[st];i++){
            int to=G[st][i];
            if(!vis[to]){pre[st]=to;nxt[to]=st;st=to;return predfs(cnt+1);}
        }
        return cnt;
    }
    int nxtdfs(int cnt){
        vis[ed]=true;
        for(int i=0;i<len[ed];i++){
            int to=G[ed][i];
            if(!vis[to]){nxt[ed]=to;pre[to]=ed;ed=to;return nxtdfs(cnt+1);}
        }
        return cnt;
    }
    bool getloop(){
        if(st==ed)return true;
        for(int i=0;i<len[ed];i++){
            int to=G[ed][i];
            if(to==st){pre[st]=ed;nxt[ed]=st;return true;}
            for(int j=0;j<len[nxt[to]];j++){
                int jto=G[nxt[to]][j];
                int tt=nxt[to];
                if(jto==st){
                    int tmp;
                    while(st!=ed){
                        nxt[ed]=to;
                        tmp=pre[to];
                        pre[to]=ed;
                        ed=to;
                        to=tmp;
                    }
                    nxt[st]=tt;
                    pre[tt]=st;
                    return true;
                }
            }
        }
        return false;
    }
    bool breakloop(){
        for(int i=1;i<=n;i++){
            if(!vis[i]){
                for(int j=0;j<len[i];j++){
                    if(vis[G[i][j]]){
                            st=i;
                            ed=pre[G[i][j]];
                            nxt[i]=G[i][j];
                            pre[G[i][j]]=st;
                            return true;
                    }
                }
            }
        }
        return false;
    }
    void printloop(){
        int sst=1,tmp=1;
        bool fl=false;
        while(sst!=tmp||!fl){
            printf("%d ",tmp);
            if(nxt[tmp]==tmp)break;
            tmp=nxt[tmp];
            fl=true;
        }
        puts("1");
    }
    void addedge(int f,int t){
        G[f][len[f]++]=t;
    }
    int main(){
        scanf("%d",&n);
        getchar();
        for(int i=1;i<=n;i++){
            int tmpt;
            while(scanf("%d",&tmpt)==1){
               if(tmpt!=i)addedge(i,tmpt);
               if(i==1)use[tmpt]=true;
               char ch=getchar();
               if(ch=='\n')break;
            }
        }
        int len=1;
        st=ed=1;
        while(len<n){
            len+=predfs(0);
            len+=nxtdfs(0);
            if(len==n)break;
            if(!getloop())break;
            if(!breakloop())break;
            len++;
        }
        getloop();
        if(len<n)puts("No solution");
        printloop();
        return 0;
    }
    

      

  • 相关阅读:
    git使用教程PDF版
    Everything(一款用于检索硬盘文件的工具)
    Animate.css(一款有意思的CSS3动画库)
    bootstrap3中container与container_fluid的区别
    河北省重大技术需求征集系统设计(七稿)第九天
    河北省重大技术需求征集系统设计(七稿)第八天
    河北省重大技术需求征集系统设计(七稿)第七天
    河北省重大技术需求征集系统设计(七稿)第六天
    河北省重大技术需求征集系统设计(七稿)第五天
    河北省重大技术需求征集系统设计(七稿)第四天
  • 原文地址:https://www.cnblogs.com/xuesu/p/4009082.html
Copyright © 2011-2022 走看看