您的位置:首页 > 其它

uva--208+dfs+回溯

2014-10-20 11:13 316 查看
题意:

给定一个无向图,求出指定两点之间的所有路线。

思路:

题意是很简单的,一开始看到最多才21个点,直接就dfs了,然后就TL;然后又把邻接矩阵改成邻接表,结果还是TL。

到网上看题解才发现,原来这个图应该是比较稠密的,这样dfs时会有很大无用的路线,非常费时;所以我们应该将与终点

相连的所有的点都找出来,然后在这些点上进行dfs;找这些点有两种方法,一种是从终点开始进行一次dfs,将所有经过的点都标记,

另一种是使用并查集;下面的代码就是使用的并查集。

注意:

一定要注意格式,写完上面的代码后提交,结果又PE了,后来才发现每行的末尾不能有空格。其实对于格式,一般都是每个案例

后面应该输出一个空行,但最后一个案例后面不要或每行中的数据之间应该要有空格而末尾不能有之类的。

代码如下:

#include<iostream>
#include<cstring>
#include<cstdio>
using namespace std;

int vis1[500],vis2[500],n,flag,num;
int fa[100],ans[500],map[30][30];

int find(int x)
{
    return fa[x]==-1?x:fa[x]=find(fa[x]);
}

void join(int x,int y)
{
    int fx=find(x);
    int fy=find(y);
    if(fx!=fy)
        fa[fx]=fy;
}

void Init()
{
    memset(map,0,sizeof(map));
    memset(fa,-1,sizeof(fa));
    memset(vis1,0,sizeof(vis1));
    memset(vis2,0,sizeof(vis2));
}

void dfs(int cur,int cnt)
{
     int i;
     if(cur==flag)
     {
         num++;
         for(i=0;i<cnt;i++)
         {
             if(i)
                printf(" ");
             printf("%d",ans[i]);
         }
         printf("\n");
         return ;
     }
     for(i=1;i<=n;i++)
        if(map[cur][i]&&!vis1[i]&&vis2[i])
        {
             vis1[i]=1;
             ans[cnt]=i;
             dfs(i,cnt+1);
             vis1[i]=0;
        }
}

int main()
{
   int i,Case=0;
   while(scanf("%d",&flag)!=EOF)
   {
       Init();
       n=0; num=0;
       while(1)
       {
           int a,b;
           scanf("%d%d",&a,&b);
           if(a==0&&b==0)
              break;
           n=max(a,n);
           n=max(b,n);
           join(a,b);
           map[a][b]=map[b][a]=1;
       }
       int m=find(flag);
       for(i=1;i<=n;i++)
          if(find(i)==m)
              vis2[i]=1;
       printf("CASE %d:\n",++Case);
       vis1[1]=1; ans[0]=1;
       dfs(1,1);
       printf("There are %d routes from the firestation to streetcorner %d.\n",num,flag);
   }
 return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: