hdu 2112(字典树+最短路)

今天挺高兴的,因为第一:我A了自己的第一道AC自动机的题目:hdu 2222;第二:我发现了自己写的字典树的代码一直以来的错误;第三:我发现了用地杰斯特拉写的最短路的算法需要注意的地方。哈哈!!!!

题意:容易理解...

分析:这道题可以说是坑得我死去活来,并不是因为它有多难,其实就是一道名副其实的水题。但是由于我的基本功出现了问题导致了各种错误,开始我是怕暴力会超时,所以我选择了用字典树来做,但是由于我的粗心:没看清地名中既有大写又有小写,所以就是一直RunTime Error,后来经过再次读题,发现了错误,通过此我以后应该把题目看清楚;然后就是我的字典树一直错的地方了,等下我会在代码中注明,出现的错误是Memory Limit Exceeded,我以为字典树做不了;于是我索性用暴力来做下,就是每出现一个字符串就和前面的所有字符串比较一次,我以为顶多是超时,但是出乎我意料的是Wrong Answer,后来经过仔细的找错误,终于被我找到了错误,哈哈!!!这个题其实用暴力也可以做,但是我觉得用字典树更好吧,因为可以少很多时间啊!!!

代码实现:

字典树+dis实现:

#include<stdio.h>
#include<string.h>
#include<stdlib.h>
int n,a[151][151],nima,visited[151];
struct node{
    int num;
    struct node *next[52];
    node()
    {
        memset(next,NULL,sizeof(next));
        num=0;
    }
};
struct node *root;
int build(char *str)//字典树
{
    struct node *p=root,*t;//这里害得我一直是超内存,我开始的时候*p=new node,然后是p=root无语了!!
    int temp;
    for(;*str!='\0';str++)
    {
        if(*str>='a'&&*str<='z')
            temp=*str-'A'-6;
        else
            temp=*str-'A';
        if(p->next[temp]==NULL)
            p->next[temp]=new node;
        p=p->next[temp];
    }
    if(p->num)
        return p->num;
    else
    {
        p->num=nima;
        nima++;
        return p->num;
    }
}
void dis()
{
   int i,j,min,depth[151],flag,cao=0;
   for(i=2;i<=n;i++)
       depth[i]=a[1][i];
   visited[1]=0;
   for(i=2;i<=n;i++)
   {
       min=100000000;
       flag=0;//开始的时候这里没有的,当出发地到目的地没有路径是就错了!!!
       for(j=2;j<=n;j++)
          if(min>depth[j]&&visited[j])
          {
              min=depth[j];
              flag=j;
          }
       if(flag==2)
       {
           printf("%d\n",min);
           cao=1;
           break;
       }
       visited[flag]=0;
       if(flag)
       for(j=2;j<=n;j++)
       {
           if(visited[j]&&depth[j]>(depth[flag]+a[flag][j]))
               depth[j]=depth[flag]+a[flag][j];
       }
   }
   if(cao==0)
       printf("-1\n");
}
void del(struct node *tree)
{
    int i;
    for(i=0;i<52;i++)
    {
        if(tree->next[i]!=NULL)
            del(tree->next[i]);
    }
    delete(tree);
}
int main()
{
   int i,j,len,t1,t2,x,y;
   char str1[35],str2[35];
   while(scanf("%d",&n)!=EOF&&n!=-1)
   {
       getchar();
       for(i=1;i<=150;i++)
           for(j=1;j<=150;j++)
           {
               if(i==j)
                   a[i][j]=0;
               else
                   a[i][j]=100000000;
               visited[i]=1;
           }
       nima=1;
       root=new node;
       scanf("%s%s",str1,str2);
       x=build(str1);
       y=build(str2);
       while(n--)
       {
          scanf("%s%s%d",str1,str2,&len);
          if(x==y)
              continue;
          t1=build(str1);
          t2=build(str2);
          if(a[t1][t2]>len)
             a[t1][t2]=a[t2][t1]=len;
          getchar();
       }
       n=nima-1;
       del(root);
       if(x==y)
           printf("%d\n",0);
       else
           dis();  
   }
   return 0;
}

暴力+最短路实现:

#include<stdio.h>
#include<string.h>
int a[161][161],visited[161],num;
char str[161][35];
int bijiao(char string[])
{
   int i;
   for(i=1;i<=num;i++)
       if(strcmp(str[i],string)==0)
           break;
   if(i==num+1)
   {
       num++;
       strcpy(str[num],string);
       return num;
   }
   else
       return i;
}
void dis()
{
    int i,j,flag,min,depth[151];
    for(i=2;i<=num;i++)
        depth[i]=a[1][i];
    visited[1]=0;
    for(i=2;i<=num;i++)
    {
        min=100000000;
        flag=0;//开始的时候这里是没有的,然后是一直错
        for(j=2;j<=num;j++)
        {
            if(visited[j]&&depth[j]<min)
            {
                min=depth[j];
                flag=j;
            }
        }
        visited[flag]=0;
        if(flag==2)
        {
            printf("%d\n",min);
            break;
        }
        if(flag)
        for(j=2;j<=num;j++)
        {
            if(visited[j]&&depth[j]>(depth[flag]+a[flag][j]))
                depth[j]=depth[flag]+a[flag][j];
        }
    }
    if(i==num+1)
        printf("-1\n");
}
int main()
{
   int n,i,j,S,E,len,t1,t2;
   char str1[35],str2[35];
   while(scanf("%d",&n)!=EOF&&n!=-1)
   {
     getchar();
     S=1;
     for(i=1;i<=160;i++)
         for(j=1;j<=160;j++)
         {
             if(i==j)
                 a[i][j]=a[j][i]=0;
             else
                 a[i][j]=a[j][i]=100000000;
             visited[i]=1;
         }
     num=1;
     scanf("%s%s",str1,str2);
     strcpy(str[1],str1);
     E=bijiao(str2); 
     for(i=1;i<=n;i++)
     {
         scanf("%s%s%d",str1,str2,&len);
         if(S!=E)
         {
            t1=bijiao(str1);
            t2=bijiao(str2);
            if(a[t1][t2]>len)
                a[t1][t2]=a[t2][t1]=len;
         }
         getchar();
     }
     if(S==E)
         printf("%d\n",0);
     else
         dis();
   }
   return 0;
}

 

posted on 2013-04-22 21:17  后端bug开发工程师  阅读(204)  评论(0编辑  收藏  举报

导航