• usaco 校园网


    题解:

    显然当一个图上的点是一个环时能满足题目要求

    那么我们来考虑怎么形成一个环

    很显然的是要先缩点

    缩完点就成为了森林,如何让森林成环呢?

    考虑一下环上的点的入度出度一定都大于1

    而连一条边可以增加某个点的入度和某个点的出度

    问题就变成了求入度为0或者出度为0的最大值

    代码:

    #include <bits/stdc++.h>
    #define rint register int
    #define IL inline
    #define rep(i,h,t) for (int i=h;i<=t;i++)
    #define dep(i,t,h) for (int i=t;i>=h;i--)
    using namespace std;
    const int N=3e5;
    struct re{
      int a,b,from;
    }e[N*2];
    int head[N],col[N],cd[N],rd[N],l,n;
    bool ins[N];
    void arr(int x,int y)
    {
      e[++l].a=head[x];
      e[l].b=y;
      e[l].from=x;
      head[x]=l;
    }
    stack<int> S;
    int cnt,color,dfn[N],low[N];
    void tarjan(int x)
    {
      S.push(x); dfn[x]=low[x]=++cnt; ins[x]=1;
      for (rint u=head[x];u;u=e[u].a)
      {
        int v=e[u].b;
        if (!dfn[v])
        {
          tarjan(v);
          dfn[x]=min(dfn[x],low[v]);
        }
        if (ins[v]) dfn[x]=min(dfn[x],dfn[v]);
      }
      if (low[x]==dfn[x])
      {
        color++;
        while (1)
        {
          int y=S.top(); S.pop(); ins[y]=0;
          col[y]=color;
          if (y==x) break;
        }
      }
    }
    int main()
    {
        freopen("1.in","r",stdin);
        freopen("1.out","w",stdout);
        ios::sync_with_stdio(false);
        cin>>n;
        for (int i=1;i<=n;i++)
        {
            while (true)
            {
              int x;
              cin>>x;
              if (x) arr(i,x); else break;
            }
        }
        int rdans=0,cdans=0;
        for (int i=1;i<=n;i++) if (!dfn[i]) tarjan(i);
        if (color==1) cout<<1<<endl<<0;
        else{
            for (int i=1;i<=l;i++)
              if (col[e[i].b]!=col[e[i].from])
                rd[col[e[i].b]]++,cd[col[e[i].from]]++;
            for (int i=1;i<=color;i++)
            {
                if (!rd[i]) rdans++;
                if (!cd[i]) cdans++;
            }
            cout<<rdans<<endl<<max(rdans,cdans);
      }
    }
    #include <bits/stdc++.h>
    using namespace std;
    int n,x,l;
    #define maxn 100000
    struct re{
        int a,b,from;
    }a[maxn];
    int color,dfn[maxn],low[maxn],col[maxn];
    int rdans,cdans,head[maxn],now,rd[maxn],cd[maxn];
    bool ins[maxn];
    int arr(int x,int y)
    {
        a[++l].a=head[x];
        a[l].b=y;
        a[l].from=x;
        head[x]=l;
    }
    stack <int> s;
    void tarjan(int x)
    {
        dfn[x]=low[x]=++now;
        int u=head[x];
        s.push(x); ins[x]=1;
        while (u)
        {
            int v=a[u].b;
            if (!dfn[v])
            {
                tarjan(v);
                low[x]=min(low[x],low[v]);
            }
            if (ins[v]) low[x]=min(low[x],dfn[v]);
            u=a[u].a;
        }
        if (dfn[x]==low[x])
        {
            color++;
            while (true)
            {
                int y=s.top();
                col[y]=color;
                s.pop();
                ins[y]=0;
                if (y==x) break;
            }
        }
    }
    int main()
    {
        freopen("noip.in","r",stdin);
        freopen("noip.out","w",stdout);
        cin>>n;
        memset(ins,0,sizeof(ins));
        for (int i=1;i<=n;i++)
        {
            while (true)
            {
              cin>>x;
              if (x) arr(i,x); else break;
            }
        }
        for (int i=1;i<=n;i++) if (!dfn[i]) tarjan(i);
        if (color==1) cout<<1<<endl<<0;
        else{
            for (int i=1;i<=l;i++)
              if (col[a[i].b]!=col[a[i].from])
                rd[col[a[i].b]]++,cd[col[a[i].from]]++;
            for (int i=1;i<=color;i++)
            {
                if (!rd[i]) rdans++;
                if (!cd[i]) cdans++;
            }
            cout<<rdans<<endl<<max(rdans,cdans);
      }
    }
  • 相关阅读:
    洗礼灵魂,修炼python(27)--异常处理(1)—>了解异常
    洗礼灵魂,修炼python(26)--编程核心之“递归”
    洗礼灵魂,修炼python(25)--自定义函数(6)—从匿名函数进阶话题讲解中解析“函数式编程”
    洗礼灵魂,修炼python(24)--自定义函数(5)—匿名函数lambda
    洗礼灵魂,修炼python(23)--自定义函数(4)—闭包进阶问题—>报错UnboundLocalError: local variable 'x' referenced before assignment
    721. Accounts Merge
    Union found
    547. Friend Circles
    200. Number of Islands
    684. Redundant Connection
  • 原文地址:https://www.cnblogs.com/yinwuxiao/p/8444680.html
Copyright © 2020-2023  润新知