UVA-208 Firetruck 消防车

这个题,就是用回溯解,但是要先优化一下,用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;
}

猜你喜欢

转载自blog.csdn.net/lky_ac/article/details/84560398
今日推荐