UVA-208 Firetruck +DFS BFS

這個題,就是用回溯解,但是要先優化一下,用bfs從終點歷遍到點1,並把這個路徑上的邊標記,在後面的dfs中只選擇被標記過的邊走,並且當點1的路徑中沒有一條被標記時,就不用dfs了。這樣優化一下就不會TL了。
還有一點就是一定要看清題目格式要求,不然就會很難受了。蠢到爆炸的我輸出語句的一個點沒寫上去,還吃了兩發WA,難受。
代碼如下:

#include<bits/stdc++.h>
using namespace std;
int have[22][22],vis[22],mark[22][22],que[22];
int n,sum;
bool is_mark(){
    int h[22][22];
    memcpy(h,have,sizeof(h));
    queue<int> q;
    q.push(n);
    while(!q.empty()){
        int g=q.front();q.pop();
        for(int i=1;i<22;i++){
            if(h[g][i]||h[i][g]){
                mark[g][i]=mark[i][g]=1;
                q.push(i);
                h[g][i]=h[i][g]=0;
            }
        }

    }
    for(int i=2;i<22;i++)
        if(mark[1][i]) return 1;
    return 0;
}
void dfs(int d,int v){
    if(v==n){
        printf("1");
        for(int i=1;i<d;i++) printf(" %d",que[i]);
        printf("\n");
        sum++;
        return;
    }
    for(int u=2;u<22;u++){
        if(!vis[u]&&have[v][u]&&mark[v][u]){
            vis[u]=1;
            have[v][u]=0;
            que[d]=u;
            dfs(d+1,u);
            vis[u]=0;
            have[v][u]=1;
        }
    }
}
int main(){
    int a,b,all=0;
    while(scanf("%d",&n)!=EOF){
        memset(have,0,sizeof(have));
        memset(vis,0,sizeof(vis));
        memset(mark,0,sizeof(mark));
        while(scanf("%d%d",&a,&b)&&a) have[a][b]=have[b][a]=1;
        sum=0;
        printf("CASE %d:\n",++all);
        if(is_mark()) dfs(1,1);
        printf("There are %d routes from the firestation to streetcorner %d.\n",sum,n);
    }
    return 0;
}

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章