zoukankan      html  css  js  c++  java
  • hdu 3594 Cactus /uva 10510 仙人掌图判定

    仙人掌图(有向):同时满足:1强连通;2任何边不在俩个环中。

    个人理解:其实就是环之间相连,两两只有一个公共点,(其实可以缩块),那个公共点是割点。HDU数据弱,网上很多错误代码和解法也可以过。

    个人解法:

    我认为:

     :仙人掌图必然是欧拉图!这样只用“入度=出度”就可以简单地判断强连通(欧拉图显然强连通)了!而且这个必要(不充分)条件还秒杀好多数据(强连通++)。

          个人证明:反证法:若有点的入度!=出度,(不妨设入度多),那么,对于每个出度,唯一从对应入度处“回来”,形成以个环,一出一入,一一对应,现在入度多的,只有从之前的出度中“回来”(鸽巢原理),这样该边在俩个环中了,矛盾。即证。

    这样只是一个必要条件罢了,还有入度==出度的,但是明显存在很多环的情况,下面用以一种普遍的解法排除即可:用dfs一遍,当发现环时(dfs发现祖先点),标记该环上所有点(祖先点/割点除外),一次,若有一个点标记俩次以上(说明有边同时在俩个环),那么必然是非仙人掌了。

    这俩个条件加起来,足以判断仙人掌图。虽然暂时无法证明其充分性,但也举不出反例。

    可以在uva10510 提交,数据强一些。

    转载请注明出处:http://write.blog.csdn.net/postedit?ref=toolbar

    代码:

    #include<iostream>
    #include<vector>
    #include<cstdio>
    #include<algorithm>
    using namespace std;
    int n;
    vector<vector<int> >e(100000);
    int ind[20010];
    int outd[20010];
    bool judge1()             //欧拉图判断      
    {
        for(int i=0;i<n;i++)
        {
            if(ind[i]!=outd[i])
               return 0;
        }
        return 1;
    }
    int vis[20010];
    int fa[20010];
    int mark[20010];
    int flag=0;
    void set(int u,int vv)   {
         mark[u]++;
         while(u!=vv)
         {
               u=fa[u]; 
               mark[u]++;
               if(mark[u]>1&&u!=vv){flag=1;return ;} 
               if(u==0)break;
         }
         mark[vv]--;
        
    }                     
    void dfs(int u)
    {
         if(flag)return ;
           for(int j=0;j<e[u].size();j++)
               {
                  int vv=e[u][j];
                        if(!vis[vv])
                         {  
                                    fa[vv]=u;
                                     vis[vv]=1;
                                    dfs(vv);
                                    
                         }
                        else 
                          set(u,vv);   
               }
         return ;  
    }     
    bool judge2()           //判定2
    {
         vis[0]=1;
         dfs(0);
         if(flag)return 0;
         for(int i=0;i<n;i++)
         {
                 if(mark[i]>1)
                   return 0;
        }
        return 1;
    }                         
    int main()
    {
        int t;
        cin>>t;
        while(t--)
        {
            cin>>n;
            for(int i=0;i<=n;i++)
              {
                    fa[i]=-1;
                  mark[i]=vis[i]=ind[i]=outd[i]=0;
                  e[i].clear();
              } 
             flag=0; 
            int ta,tb;
            scanf("%d%d",&ta,&tb);
            while(ta!=0||tb!=0)
            {
                e[ta].push_back(tb);
                outd[ta]++;
                ind[tb]++;
                scanf("%d%d",&ta,&tb);
            }
            
            if(!judge1())
            {
                printf("NO
    ");
                continue;
            }
            else
            {
                
                if(!judge2())
                  printf("NO
    ");
                else  printf("YES
    ");
            }
        }
        return 0;
        
    }
    


     

        

      
  • 相关阅读:
    android 请求网络异步载入
    A new Graph Game
    Android 高仿 频道管理----网易、今日头条、腾讯视频 (能够拖动的GridView)附源代码DEMO
    模块管理常规功能自己定义系统的设计与实现(16--模块数据的导出和打印[1])
    ganglia收集hbase的metrics
    ViewPager中View的复用
    PLY格式文件具体解释
    【RefactoringCode】The description of the refactoring book
    2.5星|《故事课2》:几个经典广告案例点评
    2星|叶檀《大破局》:2016年以来的财经时评文集,水平在平均线以下
  • 原文地址:https://www.cnblogs.com/yezekun/p/3925717.html
Copyright © 2011-2022 走看看