7-1 FireTruck 消防车 uva208

题意: 输入一个n <=20 个结点的无向图以及某个结点k   按照字典序从小到大顺序输出从结点1到结点k的所有路径  要求结点不能重复经过

标准回溯法

要实现从小到大字典序 现在数组中排序好即可   

标记数组一定要删去!!!!切记   又因为这个弄错了 

提高效率的方法:

先遍历一遍所有点  把和k点相关的点存入数组中   那些无关的点根本用不到   

同时也解决了如果 1与k不相连所造成的大量时间浪费

#include<bits/stdc++.h>
using namespace std;
#define N 22
int k;
int path[N];
int mp[N][N];
int cnt=0;
int vis[N];
vector<int>s;
void dfs1(int x)
{
    vis[x]=1;
    s.push_back(x);
    for(int i=1;i<21;i++)
        if(mp[x][i]&&!vis[i])
           dfs1(i);
}

void dfs(int node,int cur)
{
    if(node==k)
    {
        cnt++;
        printf("1");
        for(int i=1;i<cur;i++)
            printf(" %d",path[i]);
            printf("
");
    }

    for(int i=1;i<s.size();i++)
    {
        if(mp[node][s[i]])
            if(!vis[ s[i] ])
        {
            path[cur]=s[i];
            vis[ s[i] ]=1;
            dfs( s[i] ,cur+1);
            vis[ s[i] ]=0;
        }
    }
}

int main()
{   int cas=0;
    while(scanf("%d",&k)==1&&k)
    {
       int a,b;
       memset(mp,0,sizeof mp);

       while(scanf("%d %d",&a,&b)&&b&&a)
       {
           mp[a][b]=mp[b][a]=1;
       }
       s.clear();
       path[0]=1;
       cnt=0;
       dfs1(k);
       sort(s.begin(),s.end());
       memset(vis,0,sizeof vis);
        printf("CASE %d:
",++cas);
       dfs(1,1);
     printf("There are %d routes from the firestation to streetcorner %d.
", cnt, k);
    }
}
原文地址:https://www.cnblogs.com/bxd123/p/10416035.html