zoukankan      html  css  js  c++  java
  • 圆桌骑士

    链接:https://vjudge.net/contest/141787#problem/A

    题解:

    首先可以证明出

    在一个点双联通分量里,如果有奇环,那么所有点都不满足

    然后就是求点双联通了

    代码:

    #include <iostream>
    #include <algorithm>
    #include <cstdio>
    #include <cmath>
    #include <stack>
    #include <vector>
    #include <cstring>
    using namespace std;
    #define N 30000
    stack<int> s;
    int low[N],dfn[N],head[N],color[N],ff[N],now,cnt,l,n,m;
    bool odd[N],iscut[N];
    vector<int> bcc[N];
    struct re{
      int a,b,c,from;
    }a[3000000];
    bool p[2000][2000];
    void arr(int x,int y)
    {
      a[++l].a=head[x];
      a[l].b=y;
      a[l].from=x;
      head[x]=l;
    }
    void tarjan(int x,int fa)
    {
      low[x]=dfn[x]=++now;
      int child=0;
      int u=head[x];
      while (u)
      {
        int v=a[u].b;
        if (!dfn[v])
        {
          s.push(u);
          child++;
          tarjan(v,x);
          low[x]=min(low[x],low[v]);
          if (low[v]>=dfn[x])
          {
            iscut[x]=1;
            cnt++; bcc[cnt].clear();
            while (true)
            {
              int u=s.top(); s.pop();
              int y=a[u].from;
              if (ff[y]!=cnt)
              {
                bcc[cnt].push_back(y);
                ff[y]=cnt;
              }
              y=a[u].b;
              if (ff[y]!=cnt)
              {
                bcc[cnt].push_back(y);
                ff[y]=cnt;
              }
              if (a[u].from==x&&a[u].b==v) break;
            }
          }
        } else
        if (dfn[x]>dfn[v]&&v!=fa)
          s.push(u),low[x]=min(low[x],dfn[v]);
        u=a[u].a;
      }
      if (fa<0&&child==1) iscut[x]=0;
    }
    bool pd(int x,int pos)
    {
      int u=head[x],tt=1;
      while (u)
      {
        int v=a[u].b;
        if (ff[v]==pos)
        {
          if (!color[v]) 
          {
            color[v]=3-color[x];
            tt=tt&pd(v,pos);
          }
          if (color[v]!=3-color[x]) tt=0;
        }
        u=a[u].a;
      }
      return(tt);
    }
    int main()
    {
      freopen("noi.in","r",stdin);
      freopen("noi.out","w",stdout);
      std::ios::sync_with_stdio(false);
      while (cin>>n>>m&&n)
      {
        l=0; memset(head,0,sizeof(head));
        memset(ff,0,sizeof(ff));
        memset(odd,0,sizeof(odd));
        int x,y;
        memset(p,0,sizeof(p));
        for (int i=1;i<=m;i++)
          cin>>x>>y,p[x][y]=1,p[y][x]=1;
        for (int i=1;i<=n;i++)
          for (int j=1;j<=n;j++)
            if (!p[i][j]&&i!=j) arr(i,j);
       /* for (int i=1;i<=l;i++)
        {
           cout<<a[i].from<<" "<<a[i].b<<endl; 
        }*/
        now=0; cnt=0;
        memset(dfn,0,sizeof(dfn));
        memset(low,0,sizeof(low));
        memset(iscut,0,sizeof(iscut));
        for (int i=1;i<=n;i++)
          if (!dfn[i]) tarjan(i,0);
        for (int i=1;i<=cnt;i++)
        {
          memset(color,0,sizeof(color));
          for (int j=0;j<bcc[i].size();j++)
             ff[bcc[i][j]]=i;
          int x=bcc[i][0];
          color[x]=1;
          if (!pd(x,i))
            for (int j=0;j<bcc[i].size();j++)
              odd[bcc[i][j]]=1;
        }
        int ans=n;
        for (int i=1;i<=n;i++) if (odd[i]) ans--;
        cout<<ans<<endl;
      }
      return 0; 
    }
  • 相关阅读:
    10 个让人惊讶的 jQuery 插件
    URL编码方法比较
    Java大文件分片上传/多线程上传源码
    Java大文件分片上传/多线程上传代码
    Java大文件分片上传/多线程上传插件
    Java大文件分片上传/多线程上传控件
    python函数
    关于言谈
    Sql语句之select 5种查询
    openstack之网络基础
  • 原文地址:https://www.cnblogs.com/yinwuxiao/p/8835577.html
Copyright © 2011-2022 走看看