zoukankan      html  css  js  c++  java
  • UVA 10557 XYZZY 结题报告

    白书数据结构一章中最后一根刺拔掉了!  这题网上大部分都说都是SPFA ,,但是卡了我一个星期dfs 终于给我过掉了

    题意:一个有向图,每个节点都有一个值(可能小于0),给定你起始点和初始能量和终点,问你最终在 能量值大于0的情况下能否到达终点

    解题思路:dfs,bfs都试过了,最终还是用两个dfs过了,第一个dfs是判断下一个节点是否能走(依赖于第二个dfs)如果能走,如果这个节点在这条路径中走过,如果走过那么判断环的正负,如果是负环就进行第二个dfs判断能否到终点(在途中标记所有的点,如果能走到  则答案为win  如果不能,途中所有的点都不能了)!!

    如果这个节点没有走过,那么看到这个节点的之是否大于其他路径到这个节点的值(初始值 = 0  所以不用判断 是否 > 0 的情况) ,如果大于,则继续走下去!

    解题代码:

    #include <stdio.h>
    #include <string.h>
    #include <stdlib.h>
    int map[105][105];
    int limits[105];
    int value[105];
    int visit[105];
    int valuevisit[105];
    int vvisit[105];
    int canvisit[105];
    int n,ok;
    void ddfs(int k)
    {
       if(ok)
          return;
       if(k == n)
       {
         ok = 1;
         return;
       }
       for(int i = 1;i <= limits[k]; i++ )
       {
          if(!canvisit[map[k][i]])
             {
               canvisit[map[k][i]] = 1;
               ddfs(map[k][i]);
             }
       }
    
    }
    void  dfs(int k, int sum)
    {
        if(k == n && sum >0 )
        {
          ok = 1;
          return;
        }
        if(ok)
          return;
        for(int i = 1; i <= limits[k]; i ++)
        {
           if(!canvisit[map[k][i]])
            {
               if(visit[map[k][i]])
                {
                   if(sum + value[map[k][i]] > valuevisit[map[k][i]])
                     {
                         canvisit[map[k][i]] = 1;
                         ddfs(map[k][i]);
                     }
                }
               else if(sum + value[map[k][i]] > vvisit[map[k][i]])
                {
                     visit[map[k][i]] = 1;
                     valuevisit[map[k][i]] = sum + value[map[k][i]];
                     vvisit[map[k][i]] = sum + value[map[k][i]];
                     dfs(map[k][i],valuevisit[map[k][i]]);
                     valuevisit[map[k][i]] = 0;
                     visit[map[k][i]] = 0;
                }
    
            }
        }
    
    }
    int main()
    {
    
       while(scanf("%d",&n) != EOF)
       {
           if(n == -1)
             break;
           ok = 0;
           memset(map,0,sizeof(map));
           memset(visit,0,sizeof(visit));
           memset(vvisit,0,sizeof(vvisit));
           memset(canvisit,0,sizeof(canvisit));
           memset(value,0,sizeof(value));
          for(int i =1;i <= n;i ++)
          {
             scanf("%d %d",&value[i],&limits[i]);
             for(int j = 1;j  <= limits[i]; j++)
                   scanf("%d",&map[i][j]);
          }
          visit[1] = 1;
          valuevisit[1] = 100;
          dfs(1,100);
          if(ok)
            printf("winnable
    ");
          else
            printf("hopeless
    ");
       }
       return 0;
    
    }
    View Code

    在解题过程中,发现下面的有明显缺陷(在dfs后没有标记掉,判断的环不一定是一个有向环,而且也不是同一路径的环)的代码也能AC, uva的数据还是有点弱啊

    #include<stdio.h>
    #include<string.h>
    #include<stdlib.h>
    #include<time.h>
    #include<math.h>
    #include<limits.h>
    struct point
    {
        int value;
        int k; 
        int a[103];
    }points[105];
    
    int begin,end,ok ,n;
    int visit[105];
    int vvisit[105];
    int isvisit[105];
    void dfs1(int p)
    {
       //printf("%d
    ",p);
        if(p == n)
        {  
            ok = 1;
            return;
        }
        if(ok)
            return ;
        for(int i = 1;i <= points[p].k;i ++)
        {
            if(!isvisit[points[p].a[i]])
            {
                isvisit[points[p].a[i]] = 1;
                dfs1(points[p].a[i]);
            }
        }
        return ;
    
    }
    void dfs(int p ,int v)
    {
        //printf("%d
    ",p);
        if(v <= 0 )
            return;
        if(p == n)
        {  
            ok = 1;
            return;
        }
        if(ok)
            return ;
        for(int i = 1;i <= points[p].k;i ++)
        {
                if(!visit[points[p].a[i]])
                {
                    visit[points[p].a[i]] = v + points[points[p].a[i]].value;
                    dfs(points[p].a[i],v+points[points[p].a[i]].value);
                }
                else
                {
                        if(v + points[points[p].a[i]].value > visit[points[p].a[i]]  )
                        {
                            isvisit[points[p].a[i]] = 1;
                            dfs1(points[p].a[i]);
                            return;
                        }
                }
    
        }
        return ;
    }
    int main(){
    
        //freopen("/home/plac/problem/input.txt","r",stdin);
        //freopen("/home/plac/problem/output.txt","w",stdout);
        while(scanf("%d",&n) != EOF)
        {
            if(n == -1)
                break;
            begin = 0 ;
            end = 0 ;
            ok = 0 ;
            memset(points,0,sizeof(points));
            memset(visit,0,sizeof(visit));
            memset(vvisit,0,sizeof(vvisit));
            memset(isvisit,0,sizeof(isvisit));
            for(int i = 1; i <= n;i ++)
            {
    
                scanf("%d %d",&points[i].value,&points[i].k);
                for(int j =1 ;j <= points[i].k;j ++)
                {
                    scanf("%d",&points[i].a[j]);
                }
            }
            visit[1] = 100 ;
            dfs(1,100);
            if(!ok)
                printf("hopeless
    ");
            else
                printf("winnable
    ");
        }
        return 0 ;
    }
    View Code
    没有梦想,何谈远方
  • 相关阅读:
    spring mvc 源码简要分析
    tomcat 开启远程debug
    jdk1.5-jdk1.9的主要区别
    关于elasticsearch 6.x及其插件head安装(单机与集群)5分钟解决
    mysql主从配置(5分钟解决问题)
    内部类总结
    Colored Sticks
    vim 将tab转为空格
    shell编程
    vim -- 查找和替换
  • 原文地址:https://www.cnblogs.com/zyue/p/3149308.html
Copyright © 2011-2022 走看看