USACO 2009 Open Treasure Cave /// DFS||并查集 oj26215

题目大意:

输入 p,n,t ;p为地点数 判断 t 能否回到源点1

接下来n行 每行输入 a b c; a能到达b和c

Sample Input

13 6 7
6 7 8
2 3 4
10 11 12
8 9 10
1 2 13
4 5 6

Sample Output

5
1
2
4
6
7

 
可用深搜做
#include <bits/stdc++.h>
#define INF 0x3f3f3f3f
using namespace std;
int p,n,t;
int first[5005],nexti[5005],flag[5005];
int u[5005],v[5005],ans[5005],len;
bool DFS(int i,int cnt)
{
    if(i==t&&cnt<len)
    {
        len=cnt;
        ans[cnt]=i;
        return cnt;
    }
    if(cnt>len) return 0;
    int k=first[i],sign=0;
    while(k!=-1)
    {
        if(!flag[v[k]])
        {
            flag[v[k]]=1;
            if(DFS(v[k],cnt+1)!=0)
                ans[cnt]=i, sign=1;
            flag[v[k]]=0;
        }
        k=nexti[k];
    }
    if(sign) return cnt;
    else return 0;
}
int main()
{
    while(~scanf("%d%d%d",&p,&n,&t))
    {
        memset(first,-1,sizeof(first));
        memset(flag,0,sizeof(flag));
        for(int i=1;i<=n*2;i++)
        {
            scanf("%d%d",&u[i],&v[i]);
            nexti[i]=first[u[i]];
            first[u[i]]=i++;
            u[i]=u[i-1]; scanf("%d",&v[i]);
            nexti[i]=first[u[i]];
            first[u[i]]=i;
        }
        flag[1]=1;
        len=INF;
        DFS(1,1);
        printf("%d
",len);
        for(int i=1;i<=len;i++)
            printf("%d
",ans[i]);
    }

    return 0;
}
邻接表深搜

但用并查集更简单 还是简化的

#include<stdio.h>
int root[5005];
int get(int cnt,int m)
{
    if(m==1)
    {
        printf("%d
",cnt);
        return 1;
    }
    if(get(cnt+1,root[m]))
        printf("%d
",root[m]);
}
int main()
{
    int p,n,t;
    while(~scanf("%d%d%d",&p,&n,&t))
    {
        for(int i=1;i<=p;i++) root[i]=i;
        while(n--)
        {
            int a,b,c; scanf("%d%d%d",&a,&b,&c);
            root[b]=root[c]=a;
        }
        if(get(1,t)) printf("%d
",t);
    }

    return 0;
}
并查集
原文地址:https://www.cnblogs.com/zquzjx/p/8894945.html