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 }     
posted @ 2014-07-17 15:38  Naturain  阅读(89)  评论(0编辑  收藏  举报