UVA208 Firetruck 消防车(水,dfs)

要输出所有路径,又要字典序,dfs最适合了,用并查集判断1和目的地是否连通即可

#include<bits/stdc++.h>

using namespace std;

const int maxn = 21;



int p[maxn],cnt[maxn];

void init(int n) {

    for(int i = 1;i <= n; i++) p[i] = i,cnt[i] = 1;

}

int Find(int x) { return p[x] == x ? x : p[x] = Find(p[x]); }



bool G0[maxn][maxn];

int G[maxn][maxn],deg[maxn];



int maxd;

int path[maxn];

bool vis[maxn];

int k,Count;

void dfs(int d,int cur)

{

    if(cur == k){

        printf("1");

        for(int i = 1; i < d; i++)

            printf(" %d",path[i]);

        puts("");

        Count++;

        return;

    }

    if(d == maxd) return;

    for(int i = 0; i < deg[cur]; i++){

        int v = G[cur][i];

        if(vis[v]) continue;

        vis[v] = 1;

        path[d] = v;

        dfs(d+1,v);

        vis[v] = 0;

    }

}



int main()

{

    //freopen("in.txt","r",stdin);

    int cas = 0;

    while(~scanf("%d",&k)){

        printf("CASE %d:\n",++cas);

        int u,v,n = 0;

        init(20);

        memset(G0,0,sizeof(G0));

        memset(deg,0,sizeof(deg));

        while(scanf("%d%d",&u,&v),u){

            G0[u][v] = G0[v][u] = 1;

            n = max(n,v);

            n = max(n,u);

            int s1 = Find(u), s2 = Find(v);

            if(s1 != s2) {p[s1] = s2; cnt[s2] += cnt[s1];}

        }

        if(Find(k) != Find(1)) {printf("There are 0 routes from the firestation to streetcorner %d.\n",k); continue;}

        for(int i = 1; i <= n; i++)

            for(int j = 1; j <= n; j++) if(G0[i][j]){

                G[i][deg[i]++] = j;

            }

        maxd = cnt[Find(1)] ;

        memset(vis,0,sizeof(vis));

        vis[1] = 1;

        Count = 0;

        dfs(1,1);

        printf("There are %d routes from the firestation to streetcorner %d.\n",Count,k);

    }

    return 0;

}

 

你可能感兴趣的:(DFS)