• [poj2186]Popular Cows(targin缩点)


    题意:求其他所有牛都认为其牛的牛的个数。

    解题关键:targin算法模板题,缩点形成一棵树,并不一定是棵树,可能含有多个入度为0的点,寻找出度为0的点(缩点之后的点)的个数,如果个数大于0,则无解,否则输出该强连通分量内的个数。

    注意targin算法的数组不需要memset。

     1 #include<iostream>
     2 #include<cstring>
     3 #include<cstdio>
     4 #include<cstdlib>
     5 #include<cmath>
     6 #include<algorithm>
     7 using namespace std;
     8 typedef long long ll;
     9 #define MAXN 10010
    10 #define MAXM 100010
    11 struct edge{
    12     int to,nxt;
    13 }e[MAXM];
    14 int degree[MAXN];
    15 int head[MAXN],st[MAXN],dfn[MAXN],lowest[MAXN],belong[MAXN];
    16 bool inst[MAXN];
    17 int n,m,scnt,top,tot;//scnt从1开始
    18 void init(){
    19     memset(head,-1,sizeof head);
    20     memset(degree,0,sizeof degree);
    21     scnt=top=tot=0;
    22 }
    23 
    24 void add_edge(int u, int v){
    25     e[tot].to=v;
    26     e[tot].nxt=head[u];
    27     head[u]=tot++;
    28 }
    29 
    30 void Tarjan(int u){
    31     dfn[u]=lowest[u]=++tot;
    32     inst[u]=1;
    33     st[top++]=u;
    34     for(int i=head[u];i!=-1;i=e[i].nxt){
    35         int v=e[i].to;
    36         if(!dfn[v]){
    37             Tarjan(v);
    38             lowest[u]=min(lowest[u],lowest[v]);
    39         }
    40         else if(inst[v]){
    41             lowest[u]=min(lowest[u],dfn[v]);//也可用lowest
    42         }
    43     }
    44     if(dfn[u]==lowest[u]){
    45         scnt++;
    46         int t;
    47         do{
    48             t=st[--top];
    49             inst[t]=false;
    50             belong[t]=scnt;
    51         }while(t!=u);
    52     }
    53 }
    54 
    55 inline int read(){
    56     char k=0;char ls;ls=getchar();for(;ls<'0'||ls>'9';k=ls,ls=getchar());
    57     int x=0;for(;ls>='0'&&ls<='9';ls=getchar())x=(x<<3)+(x<<1)+ls-'0';
    58     if(k=='-')x=0-x;return x;
    59 }
    60 
    61 
    62 void solve(){//缩点
    63     for(int i=1;i<=n;i++)  if(!dfn[i])  Tarjan(i);
    64     for(int i=1;i<=n;i++){
    65         for(int j=head[i];j!=-1;j=e[j].nxt){
    66             if(belong[i]!=belong[e[j].to]){
    67                 degree[belong[i]]++;
    68             }
    69         }
    70     }
    71     int sum=0,x=0;
    72     for(int i=1;i<=scnt;i++) if(!degree[i]) sum++,x=i;//记录索引
    73     if(sum!=1){
    74         printf("0
    ");
    75         return;
    76     }
    77     sum=0;
    78     for(int i=1;i<=n;i++){
    79         if(belong[i]==x) sum++;
    80     }
    81     printf("%d
    ",sum);
    82     return;
    83 }
    84 
    85 int main(){
    86     int a,b;
    87     while(scanf("%d%d",&n,&m)!=EOF){
    88         init();
    89         while(m--){
    90             a=read(),b=read();
    91             add_edge(a,b);
    92         }
    93         solve();
    94     }
    95     return 0;
    96 }
  • 相关阅读:
    流式布局思想
    盒子的显隐
    高级布局 浮动 清浮动
    display总结 overflow知识
    边界圆角 盒模型布局 图片背景 精灵图
    io模型
    协程
    GIL 进程池与线程池
    守护进程 互斥锁 进程间通讯
    子进程
  • 原文地址:https://www.cnblogs.com/elpsycongroo/p/7521164.html
Copyright © 2020-2023  润新知