• 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;
    }
  • 相关阅读:
    【USACO10JAN】Cheese Towers S 奶酪塔 (背包dp)
    【SDOI2015】排序(dfs+结论)
    【NOI2014】购票(树形dp+树剖+斜率优化)
    【BZOJ3329】Xorequ(数位dp+矩阵快速幂)
    [NOI 2012] 骑行川藏
    BZOJ
    [学习笔记] 上下界网络流
    [八省联考 2018] 劈配
    P4313 文理分科
    [SDOI 2015] 序列统计
  • 原文地址:https://www.cnblogs.com/jiangjing/p/3036637.html
Copyright © 2020-2023  润新知