• 1051: [HAOI2006]受欢迎的牛 (tarjan强连通分量+缩点)


    题目大意:CodeVs2822的简单版本


    传送门

    $Tarjan$强连通分量+缩点,若连通块的个数等于一则输出n;若缩点后图中出度为0的点个数为1,输出对应连通块内的点数;否则输出0;

    代码中注释部分是调了半个小时没发现有错的地方。。。

     1 #include<cstring>
     2 #include<cstdio>
     3 #include<cmath>
     4 #include<algorithm>
     5 #include<cctype>
     6 #define foru(i,x,y) for(int i=x;i<=y;i++)
     7 #define ford(i,x,y) for(int i=x;i>=y;i--)
     8 #define re(x) x=read()
     9 using namespace std;
    10 typedef long long LL;
    11 typedef double db;
    12 const int inf=1e9;
    13 const int N=1e6+10;
    14 
    15 struct edge{int to,nxt;}e[N*2];
    16 int dfn[N],low[N],stk[N],head[N],vis[N],bl[N],out[N],x,cnt,cl,ed,ne,n,m,ans;
    17 
    18 void add(int a,int b){
    19     e[++ne]=(edge){b,head[a]};head[a]=ne;
    20 }
    21 
    22 int read(){
    23     static int f,x;static char ch;
    24     x=f=0;ch=getchar();
    25     while(!isdigit(ch)){f=(ch=='-');ch=getchar();}
    26     while(isdigit(ch)){x=x*10+ch-'0';ch=getchar();}
    27     return f?-x:x;
    28 }
    29 
    30 void tarjan(int k){
    31     dfn[k]=low[k]=++cnt;stk[++ed]=k;vis[k]=1;
    32     for(int i=head[k];i;i=e[i].nxt){
    33         int v=e[i].to;
    34         if(!dfn[v]){
    35             tarjan(v);
    36             low[k]=min(low[k],low[v]);
    37         }
    38         else if(vis[v])low[k]=min(low[k],dfn[v]);
    39     }
    40     int p;
    41     if(low[k]==dfn[k]){
    42         cl++;//x++;
    43         do{
    44             p=stk[ed--];
    45             bl[p]=cl;
    46             vis[p]=0;
    47         }while(p!=k);
    48     }
    49 }
    50 
    51 int main(){
    52     int u,v;
    53     re(n);re(m);
    54     foru(i,1,m){
    55         re(u);re(v);
    56         add(u,v);
    57     }
    58     foru(i,1,n)if(!dfn[i])tarjan(i);
    59     if(cl==1){printf("%d
    ",n);return 0;}
    60     foru(k,1,n)
    61         for(int i=head[k];i;i=e[i].nxt)
    62             if(bl[k]!=bl[e[i].to])out[bl[k]]++;
    63     v=0;
    64     foru(i,1,cl)if(!out[i]){v++;u=i;}
    65     if(v==1){
    66         foru(i,1,n)if(bl[i]==u)ans++;
    67         printf("%d
    ",ans);return 0;
    68     }
    69     else puts("0");
    70     
    71 //    if(v==1)
    72 //        foru(i,1,n)if(bl[i]==u)ans++;
    73 //    else ans=0;
    74 //    printf("%d
    ",ans);
    75     return 0;
    76 }
  • 相关阅读:
    利用事件委托实现用户控件中的行为触发所在页面的处理函数
    mootools系列:打造属于你自己的Popup(弹出框)——基本结构篇
    mootools系列:打造属于你自己的Popup(弹出框)——外观及应用篇
    所见即所得的Excel报表生成(二)——从Html table到Excel Cell
    Excel操作服务器端配置
    顺丰单号生成规则
    代理模式Proxy
    解释器模式Interpreter
    线性表
    总有一款合适的框架
  • 原文地址:https://www.cnblogs.com/y-m-y/p/7681749.html
Copyright © 2020-2023  润新知