POJ 2023 Choose Your Own Adventure(树形,dfs,简单题)

题意:
  输入一个整数n,表示有n组测试数据,
  每组第一行输入一个整数x表示该组测试一共有x页,接下来输入x行,每行表示一页,
  每页或者以C开头(第一页都是以C开头),或者以E开头,中间用引号括起一段文字。
  以C开头的末尾输入两个数字a,b表示该页完后可以跳转到第a页或第b页,
  以E开头的末尾输入一个单词,或者是HAPPY或者是GRISLY(有且仅有一页以HAPPY结尾)。
  现在要求你根据输入找出以第一页开头,以HAPPY结尾的路径,输出路径上每一页中间引号里面的内容,不包含引号。

思路:建立树,用dfs深搜。
  要注意的是数据中可能会有死循环出现,会导致RE。。。

另外:本题读取句子可采用的方法:
cin.getline(page[j],258,'"')
参考网址
http://hi.baidu.com/kskr/blog/item/cb00cc3deadf45c49f3d6279.html

#include <iostream>
#include <stdio.h>
#include <map>
#include <string.h>
#include <algorithm>

const int maxn=110;
using namespace std;
int t,n;  
int endnum;  //以HAPPY结尾的页数
int pri[maxn];  //前驱
bool ok;  //标记是否已经找到路径
int vis[maxn];  //标记该页数是否被访问过

struct Page{
    int mark;
    char sentence[300];
    int len;
    int son[2];  //跳转的页码
    char ending[10]; 
    bool flag;  //flag为true表示该页是HAPPY
}page[maxn];

void dfs(int u){
    if(ok)
        return;
    vis[u]=1;  //没用vis标记前,RE;后来网上查了,有人说数据中有循环,便加上了标记,结果WA,忘记输出STORY X了。。。
    if(page[u].mark){
        for(int i=0;i<2;i++){
            int v=page[u].son[i];
            if(!vis[v]){
                pri[v]=u;
                dfs(v);
            }
        }
    }
    else{
        if(page[u].flag){
            ok=true;
            endnum=u;
        }
    }
}
int main()
{
    char s[3];
    char c;
    int len;
    cin>>t;
    for(int q=1;q<=t;q++){
        cout<<"STORY "<<q<<endl;
        memset(pri,-1,sizeof(pri));
        memset(vis,0,sizeof(vis));
        cin>>n;
        for(int i=1;i<=n;i++){
            scanf("%s",s);
            page[i].mark=0;
            if(s[0]=='C'){
                page[i].mark=1;
                c=getchar();
                while(c!='"')
                    c=getchar();
                len=0;
                //读取双引号里的句子
                while((c=getchar())!='"')
                    page[i].sentence[len++]=c;
                page[i].len=len;
                scanf("%d%d",&page[i].son[0],&page[i].son[1]);
            }
            else{
                c=getchar();
                while(c!='"')
                    c=getchar();
                len=0;
                //读取双引号里的句子
                while((c=getchar())!='"')
                    page[i].sentence[len++]=c;
                page[i].len=len;

                scanf("%s",page[i].ending);
                if(strcmp(page[i].ending,"HAPPY")==0){
                    page[i].flag=true;
                }
                else{
                    page[i].flag=false;
                }
            }
        }
        pri[1]=1;
        ok=false;
        dfs(1);
        int idx=0;
        int res[maxn];
        res[idx++]=endnum;
        //存储路径
        while(pri[endnum]!=endnum){
            res[idx++]=pri[endnum];
            endnum=pri[endnum];
        }
        for(int i=idx-1;i>=0;i--){
            for(int j=0;j<page[res[i]].len;j++){
                cout<<page[res[i]].sentence[j];
            }
            cout<<endl;
        }
    }
    return 0;
}
原文地址:https://www.cnblogs.com/chenxiwenruo/p/3525129.html