zoukankan      html  css  js  c++  java
  • hdu 1811 ufset综合

    好久没敲了,手生。

    题意:给一个图,要求是没有环。而且能从一点出发一笔画全然部点。

    定性推断出来。

    想恢复一下算法。推断矛盾用的强连通性的tarjan,不能确定用的模拟。

    #include<iostream>
    #include<cstdio>
    #include<set>
    #include<stack>
    #include<vector>
    using namespace std;
    int fa[30105];  int n,m; int ind[30028];
    int find(int x)
    {
        if(x==fa[x])return x;
        fa[x]=find(fa[x]);
        return fa[x];
    }
    int e[100154][3];int head[30023];int nume;
    void inline adde(int i,int j)
    {
        e[nume][0]=j;e[nume][1]=head[i];head[i]=nume++;
    }
    struct zz
    {
        int x,y;
        char t;
    };
    int ins[20009];stack<int>sta;int low[20025];int dfn[20025];
    int times;int vis[20025];int scc[20251];int numb=0;
    void tarjan(int u)
    {
        dfn[u]=low[u]=times++;
        ins[u]=1;
        sta.push(u);
        for(int j=head[u];j!=-1;j=e[j][1])
        {
            int v=e[j][0];
            if(!vis[v])
            {
                vis[v]=1;
                tarjan(v);
                if(low[u]>low[v])low[u]=low[v];
            }
            else if(ins[v])
            {
                if(dfn[v]<low[u])low[u]=dfn[v];
            }
        }
        if(low[u]==dfn[u])
        {
            numb++;
            int cur;
            do
            {
                cur=sta.top();
                sta.pop();
                ins[cur]=0;
                scc[cur]=numb;
            }while(cur!=u);
        }
    }
    int judge()
    {
        int ss=-1;
        int cnt=0;int numv=0;
        set<int>temp;
        for(int i=0;i<n;i++)
        {
            int tx=find(i);
            temp.insert(tx);
            if(ind[tx]==0&&tx==i)     //開始没有加这个后面条件,WA了好几发。。。

    { ss=tx; cnt++; } } numv=temp.size(); for(int i=0;i<n;i++) { int tx=find(i); if(!vis[tx]) { vis[tx]=1; tarjan(tx); } } if(numb!=numv)return 1; //有矛盾 if(cnt!=1)return 2; int cur=ss; while(numv!=0) { cnt=0; for(int j=head[cur];j!=-1;j=e[j][1]) { int to=e[j][0]; ind[to]--; if(ind[to]==0) { cur=to; cnt++; } } if(cnt>1)return 2; numv--; } return 0; } void init() { for(int i=0;i<10005;i++) { fa[i]=i; head[i]=-1; low[i]=dfn[i]=0; scc[i]=vis[i]=ins[i]=ind[i]=0; } numb=times=nume=0; } int main() { while(~scanf("%d%d",&n,&m)) { int marks=0; int aa,bb;char temp; init(); vector<zz>my; for(int i=0;i<m;i++) { cin>>aa>>temp>>bb; if(temp=='=') { int xx=find(aa); int yy=find(bb); if(xx!=yy)fa[xx]=yy; } else { zz cur; cur.x=aa;cur.y=bb;cur.t=temp; my.push_back(cur); } } for(int i=0;i<my.size();i++) { if(my[i].t=='<') { int xx=find(my[i].x); int yy=find(my[i].y); if(xx==yy)marks=1; adde(yy,xx); ind[xx]++; } else { int xx=find(my[i].x); int yy=find(my[i].y); if(xx==yy)marks=1; adde(xx,yy); ind[yy]++; } } int ans=judge(); if(n==0) ans=0; if(ans==2&&marks!=1) printf("UNCERTAIN "); else if(ans==1||marks==1) printf("CONFLICT "); else printf("OK "); } return 0; }



    传统方法: ufset拓扑:

    #include<iostream>
    #include<cstdio>
    #include<set>
    #include<stack>
    #include<vector>
    using namespace std;
    const int maxn=100004;
    int fa[maxn];  int n,m; int ind[maxn];
    int sums=0;
    vector<vector<int> >e(maxn);
    int find(int x)
    {
        if(x==fa[x])return x;
        fa[x]=find(fa[x]);
        return fa[x];
    }
    struct zz
    {
        int x,y;
        char t;
    };
    int judge()
    {
        int ans=0;
        stack<int>mys;
        for(int i=0;i<n;i++)
        {
            int tx=find(i);
            if(ind[tx]==0&&tx==i)
               {
                   mys.push(tx);
               }
        }
        while(!mys.empty())
        {
            int cnt=0;
           int cur=mys.top();
           if(mys.size()!=1)ans=2;
           mys.pop();
           sums--;
          for(int i=0;i<e[cur].size();i++)
           {
            int to=e[cur][i];
            ind[to]--;
            if(ind[to]==0)
            {
                mys.push(to);
            }
          }
        }
        if(sums!=0)ans=1;
        return ans;
    }
    void init()
    {
          for(int i=0;i<maxn-1;i++)
             {
                 fa[i]=i;
                ind[i]=0;
                e[i].clear();
             }
    
           sums=n;
    }
    int main()
    {
      while(~scanf("%d%d",&n,&m))
      {
          int aa,bb;char temp;
          init();
            vector<zz>my;
          for(int i=0;i<m;i++)
          {
            cin>>aa>>temp>>bb;
            if(temp=='=')
            {
                int xx=find(aa);
                int yy=find(bb);
                if(xx!=yy){fa[xx]=yy;sums--;}
            }
            else
            {
               zz cur;
                cur.x=aa;cur.y=bb;cur.t=temp;
               my.push_back(cur);
            }
          }
          for(int i=0;i<my.size();i++)
          {
              if(my[i].t=='<')
                {
                  int xx=find(my[i].x);
                  int yy=find(my[i].y);
                   e[yy].push_back(xx);
                   ind[xx]++;
                }
              else if(my[i].t=='>')
              {
                  int xx=find(my[i].x);
                  int yy=find(my[i].y);
                    e[xx].push_back(yy);
                  ind[yy]++;
              }
          }
          int ans=judge();
          if(n==0) ans=0;
           if(ans==2)
            printf("UNCERTAIN
    ");
           else if(ans==1)
           printf("CONFLICT
    ");
           else
           printf("OK
    ");
      }
      return 0;
    }
    



  • 相关阅读:
    Drawable、Bitmap、byte[]之间的转换
    关于java.lang.IllegalArgumentException: View not attached to window manager 错误的分析
    Android ListView使用BaseAdapter与ListView的优化
    Ubuntu, using svn from terminal
    Ubuntu 12.04(64位)上搭建android 开发环境 (ADT 、android-studio)
    Widget改变大小
    android4.0中实现AppWidget集合
    android 中 AppWidget 的 ListView 的实现
    解决IllegalStateException: Can not perform this action after onSaveInstanceState
    Drawable和Bitmap转换
  • 原文地址:https://www.cnblogs.com/wgwyanfs/p/7397727.html
Copyright © 2011-2022 走看看