Uva--208(回溯)
2014-07-17 15:31:29
题意&思路:大概意思就是给出无向图,求从起点到终点的所有路径和路径总数。这题由于结点数最多21个,总情况数可能达到1!+(1!+2!)+(1!+2!+3!)+....+(1!+2!+....+21!)非常大,所以需要剪枝,方案1:从终点开始向前搜,把能直接或间接到达终点的点表示valid(有效);方案二:并查集,把和终点连通的点标记。
1 #include <cstdio> 2 #include <iostream> 3 #include <cstring> 4 #include <cmath> 5 using namespace std; 6 7 int ed,g[25][25],used[25],s[25],valid[25],num,tmax; 8 9 void Dfs(int cur,int cnt){ 10 if(cur == ed){ 11 for(int i = 1; i <= cnt; ++i){ 12 printf("%d",s[i]); 13 if(i != cnt) printf(" "); 14 } 15 puts(""); 16 ++num; 17 return; 18 } 19 for(int i = 2; i <= tmax; ++i){ 20 if(g[cur][i] && !used[i] && valid[i]){ 21 s[cnt + 1] = i; 22 used[i] = 1; 23 Dfs(i,cnt + 1); 24 used[i] = 0; 25 } 26 } 27 } 28 29 void Check(int cur){ 30 valid[cur] = 1; 31 for(int i = 2; i <= tmax; ++i){ 32 if(g[cur][i] && !valid[i]){ 33 Check(i); 34 } 35 } 36 } 37 38 int main(){ 39 int a,b,Case = 0,bigger; 40 while(scanf("%d",&ed) == 1){ 41 printf("CASE %d:\n",++Case); 42 memset(used,0,sizeof(used)); 43 memset(valid,0,sizeof(valid)); 44 memset(g,0,sizeof(g)); 45 tmax = -1; 46 while(scanf("%d%d",&a,&b) == 2){ 47 if(a == 0 && b == 0) 48 break; 49 bigger = max(a,b); 50 tmax = max(tmax,bigger); 51 g[a][b] = 1; 52 g[b][a] = 1; 53 } 54 num = 0; 55 s[1] = 1; 56 used[1] = 1; 57 Check(ed); 58 Dfs(1,1); 59 printf("There are %d routes from the firestation to streetcorner %d.\n",num,ed); 60 } 61 return 0; 62 }