枚举所有可能的路径
要注意的是:
1》并查集判联通
2》如果一个点的下一个点就是goal,那么当直接判断出来后,不能够直接返回,应该去continue
下面是AC代码
#include<cstdio> #include<cstring> using namespace std; const int maxn = 30; int G[maxn][maxn]; int goal; int cnt = 0; int pa[maxn]; int find(int x) { if(pa[x] != x) { pa[x] = find(pa[x]); } return pa[x]; } bool read_G() { //读图 memset(pa,0,sizeof(pa)); memset(G,0,sizeof(G)); for(int i = 1;i <= 21;i++) { pa[i] = i;//初始化并查集 } if(scanf("%d",&goal) != 1) return false; int x1,x2; while(scanf("%d%d",&x1,&x2) == 2 && x1) { G[x1][x2] = G[x2][x1] = 1; int s1 = find(x1),s2 = find(x2); if(s1 != s2)//直接联通 { pa[s1] = pa[s2]; } } return true; } int ans[maxn]; int vis[maxn]; void print_ans(int pos) { cnt++; for(int i = 0;i <= pos;i++) { if(i) printf(" "); printf("%d",ans[i]); } printf("\n"); } void dfs(int cur) { for(int i = 1;i <= 21;i++) { if(G[ans[cur - 1]][i] == 1 && !vis[i]) { vis[i] = 1; ans[cur] = i; if(i == goal) { print_ans(cur); vis[i] = 0; continue;//这个地方刚才出错了 } dfs(cur + 1); vis[i] = 0; } } } int main() { //freopen("input.txt","r",stdin); //freopen("out.txt","w",stdout); int kase = 0; while(read_G()) { cnt = 0; printf("CASE %d:\n",++kase); //注意两个点联通和并查集判断联通块个数的区别 if(find(1) != find(goal)) { printf("There are 0 routes from the firestation to streetcorner %d.\n",goal); continue; } else if(goal == 1) { printf("1\n"); printf("There are 1 routes from the firestation to streetcorner %d.\n",goal); continue; } memset(vis,0,sizeof(vis)); ans[0] = 1; vis[1] = 1; dfs(1); printf("There are %d routes from the firestation to streetcorner %d.\n",cnt,goal); } return 0; }