zoukankan      html  css  js  c++  java
  • [HAOI2006]受欢迎的牛

    题目:BZOJ1051、洛谷P2341。

    题目大意:给你一张有向图,问有多少个点能从其他任意点到达。

    解题思路:首先求强连通分量,缩点。

    然后就变成有向无环图上的问题了。

    这里有一个巧妙的思路:找出度为0的点。

    由于是有向无环图,任意一个能从其他点到达的点出度一定是0,否则就会有环。

    而这样的点最多有一个,如果有多个这样的点,它们两两之间已经不连通,已经不符合题意。

    所以求各个点的出度,当只有一个出度为0的点(强连通分量)时,输出它原来包含的点的个数,否则输出0即可。

    C++ Code:

    #include<cstdio>
    #include<cctype>
    #include<cstring>
    #include<set>
    using namespace std;
    #define N 10005
    int n,m,head[N],dfn[N],low[N],sta[N],ys[N],sz[N],top,idx,ltfl;
    bool vis[100005];
    set<int>deg[N];
    struct edge{
      int from,to,nxt;
    }e[100005];
    inline int readint(){
      char c=getchar();
      for(;!isdigit(c);c=getchar());
      int d=0;
      for(;isdigit(c);c=getchar())
      d=(d<<3)+(d<<1)+(c^'0');
      return d;
    }
    void tarjan(int now){
      vis[sta[++top]=now]=true;
      dfn[now]=low[now]=++idx;
      for(int i=head[now];i;i=e[i].nxt)
      if(!dfn[e[i].to]){
        tarjan(e[i].to);
        if(low[now]>low[e[i].to])
        low[now]=low[e[i].to];
      }else
      if(vis[e[i].to]&&low[now]>dfn[e[i].to])
      low[now]=dfn[e[i].to];
      if(dfn[now]==low[now]){
        ++ltfl;
        int k;
        do{
          vis[k=sta[top--]]=false;
          ys[k]=ltfl;
          ++sz[ltfl];
        }while(k!=now);
      }
    }
    int main(){
      top=ltfl=0;
      memset(head,0,sizeof head);
      n=readint(),m=readint();
      for(int i=1;i<=m;++i){
        int x=readint(),y=readint();
        e[i]=(edge){x,y,head[x]};
        head[x]=i;
      }
      memset(dfn,0,sizeof dfn);
      memset(low,0,sizeof low);
      for(int i=1;i<=n;++i)
      if(!dfn[i]){
        idx=0;
        memset(vis,0,sizeof vis);
        tarjan(i);
      }
      for(int i=1;i<=m;++i)
      if(ys[e[i].to]!=ys[e[i].from]&&!deg[ys[e[i].to]].count(ys[e[i].from]))
      deg[ys[e[i].from]].insert(ys[e[i].to]);
      int ans=0;
      bool b=false;
      for(int i=1;i<=ltfl;++i)
      if(!deg[i].size()){
        if(b){
          puts("0");
          return 0;
        }
        ans=sz[i];
        b=true;
      }
      printf("%d
    ",ans);
      return 0;
    }
    
  • 相关阅读:
    类加载器
    hibernate笔记
    windows笔记
    maven笔记
    mysql笔记
    jsonp使用
    [ZJU 1010] Area
    [ZJU 1004] Anagrams by Stack
    [ZJU 1003] Crashing Balloon
    [ZJU 1002] Fire Net
  • 原文地址:https://www.cnblogs.com/Mrsrz/p/7766004.html
Copyright © 2011-2022 走看看