zoukankan      html  css  js  c++  java
  • POJ 2186 Tarjan缩点构图+处理度数

    题目链接: http://poj.org/problem?id=2186

    题目大意:

      给定一个n,m( 1<=n<=10000, 0<=m<=50000 )代表n头牛,m个关系,然后是m行,每行一个u,v代表 牛u认为牛v是popular的, 问有多少头牛被其他所有牛认为是popular的;

    分析:

      Tarjan缩点后,dfs扫描处理出每个强连通分量(SCC)的度数即可,关键是结论。

      这题的答案应该是出度 out[i] == 0 的SCC的个数必须为1。  

      (开始我考虑好多情况,唯一漏掉的情况在我下载USACO的数据后被我发现了;)

    代码:

    POJ 2186
      1 /*2186    Accepted    728K    79MS    C++    2618B    2012-04-18 19:09:52*/
      2 #include <cstdio>
      3 #include <cstring>
      4 #include <cmath>
      5 #include <iostream>
      6 #include <algorithm>
      7 #include <vector>
      8 using namespace std;
      9 
     10 #define mpair make_pair
     11 #define pii pair<int,int>
     12 #define MM(a,b) memset(a,b,sizeof(a));
     13 typedef long long lld;
     14 typedef unsigned long long u64;
     15 template<class T> bool up_max(T& a,const T& b){return b>a? a=b,1 : 0;}
     16 template<class T> bool up_min(T& a,const T& b){return b<a? a=b,1 : 0;}
     17 #define maxn 10020
     18 
     19 int n,m,top;
     20 struct Edge{
     21     int v;
     22     Edge *next;
     23 } *adj[maxn], edge[50010];
     24 void Addedge(int u,int v){
     25     Edge *p= &edge[++top];
     26     p->v= v;
     27     p->next= adj[u];
     28     adj[u]= p;
     29 }
     30 
     31 int Bcnt, Top, Index;
     32 int c[maxn], belong[maxn];
     33 int stack[maxn], dfn[maxn], low[maxn];
     34 bool instack[maxn];
     35 
     36 void Tarjan(int u){
     37     instack[u]= 1;
     38     stack[++Top]= u;
     39     dfn[u]= low[u]= ++Index;
     40     for(Edge *p= adj[u];p;p= p->next){
     41         int v= p->v;
     42         if( !dfn[v] ){
     43             Tarjan( v );
     44             up_min( low[u], low[v] );
     45         }
     46         else if( instack[v] )
     47             up_min( low[u], dfn[v] );
     48     }
     49     if( low[u]==dfn[u] ){
     50         Bcnt++;
     51         c[Bcnt]= 0; /// Init;
     52         int v;
     53         do{
     54             v= stack[Top--];
     55             instack[v]= 0;
     56             belong[v]= Bcnt;
     57             c[Bcnt]++;
     58         }while( u!=v );
     59     }
     60 }
     61 
     62 bool vis[maxn];
     63 int out[maxn];
     64 void dfs(int u){
     65     vis[u]= 1;
     66     for(Edge *p= adj[u];p;p= p->next){
     67         int v= p->v;
     68         if( belong[v] != belong[u] ){
     69             out[ belong[u] ]++;
     70         }
     71         if( !vis[v] )
     72             dfs( v );
     73     }
     74 }
     75 
     76 int main()
     77 {
     78     while(scanf("%d%d", &n, &m)!=EOF){
     79         top= 0;
     80         MM( adj, 0 );
     81         int i, u, v;
     82         for(i=1;i<=m;++i){
     83             scanf("%d%d", &u, &v);
     84             Addedge( u, v );
     85         }
     86         if( 1==n ){
     87             puts("0");
     88             continue;
     89         }
     90 
     91         Bcnt= Top= Index= 0;
     92         for(i=1;i<=n;++i) dfn[i]= low[i]= instack[i]= 0;
     93         for(i=1;i<=n;++i){
     94             if( !dfn[i] )
     95                 Tarjan( i );
     96         }
     97 
     98         if( Bcnt==1 ) printf("%d\n", n);
     99         else{
    100             fill( out+1, out+1+Bcnt, 0 );
    101             fill( vis+1, vis+1+n, 0 );
    102             for(i=1;i<=n;++i)
    103                 if( !vis[i] )
    104                     dfs( i );
    105 
    106             int c2=0, t;
    107             for(i=1;i<=Bcnt;++i)
    108                 if( out[i]==0 ){
    109                     c2++; t=i;
    110                 }
    111             if( c2==1 ) printf("%d\n", c[t]);
    112             else puts("0");
    113         }
    114     }
    115 }
    一毛原创作品,转载请注明出处。
  • 相关阅读:
    shell入门-cut命令
    shell入门-特殊符号
    shell入门-系统和用户的配置文件
    shell入门-变量
    shell入门-shell特性
    linux命令-yum工具详解
    linux命令-rpm查询包
    linux命令-rpm安装和卸载
    math 数学模块
    random 随机模块
  • 原文地址:https://www.cnblogs.com/yimao/p/2455774.html
Copyright © 2011-2022 走看看