• 最受欢迎的牛 usaco


    题面网上到处都是;

    主要来谈谈怎么做,首先利用tarjan求强连通分量缩点,缩点后找到出度为0的点,若不止一个,则输出0,否则输出这个点包含的缩点前的点的个数;

    为什么这么做,是由这道题的问法决定的,若最后求出的出度为0的点有多个,可以肯定一定没有所求的牛;

    代码:

     1 #include<iostream>
     2 #include<cstdio>
     3 #include<cstdlib>
     4 #include<cstring>
     5 #include<string>
     6 #include<algorithm>
     7 using namespace std;
     8 const int maxn=10100;
     9 int n,m;
    10 int pre[maxn],low[maxn],sccno[maxn],scc_cnt=0,dfs_clock=0,z[maxn],top=0,out[maxn];
    11 bool b[maxn][maxn];
    12 struct node{
    13     int y,next;
    14 }e[maxn<<4];
    15 int linkk[maxn],len=0;
    16 void insert(int x,int y){
    17     e[++len].y=y;
    18     e[len].next=linkk[x];
    19     linkk[x]=len;
    20 }
    21 void dfs(int x){
    22     pre[x]=low[x]=++dfs_clock;
    23     z[++top]=x;
    24     for(int i=linkk[x];i;i=e[i].next){
    25         if(!pre[e[i].y]){
    26             dfs(e[i].y);
    27             if(low[e[i].y]<low[x])low[x]=low[e[i].y];
    28         }
    29         else if(!sccno[e[i].y])
    30             low[x]=min(low[x],pre[e[i].y]);
    31     }
    32     if(low[x]==pre[x]){
    33         scc_cnt++;
    34         while(true){
    35             sccno[z[top]]=scc_cnt;
    36             if(z[top]==x){top--;break;}
    37             top--;
    38         }
    39     }
    40 }
    41 void print(int x){printf("%d
    ",x);exit(0);}
    42 void init(){
    43     scanf("%d%d",&n,&m);
    44     int x,y;
    45     for(int i=1;i<=m;i++){
    46         scanf("%d%d",&x,&y);
    47         insert(x,y);
    48     }
    49 }
    50 void slove(){
    51     for(int i=1;i<=n;i++)if(!pre[i])dfs(i);
    52     int x,y;
    53     for(int j=1;j<=n;j++)
    54         for(int i=linkk[j];i;i=e[i].next){
    55             x=sccno[j],y=sccno[e[i].y];
    56             if(x==y||b[x][y])continue;
    57             b[x][y]=1;out[x]++;
    58         }
    59     int k=0;
    60     for(int i=1;i<=scc_cnt;i++){
    61         if(!out[i]&&k){k=-1;break;}
    62         if(!out[i]&&!k)k=i;
    63     }
    64     if(k==-1)print(0);
    65     int sum=0;
    66     for(int i=1;i<=n;i++)if(sccno[i]==k)sum++;
    67     print(sum);
    68 }
    69 int main(){
    70     init();
    71     slove();
    72     return 0;
    73 }
    View Code
  • 相关阅读:
    《将博客搬至CSDN》
    关于数据分析师出路的思考
    什么样的人适合学金融工程?
    再谈到计算机网络的学习
    学习金融工程的随笔
    走上量化投资道路的回顾
    idea构建docker镜像并发布到服务器
    Elastic:菜鸟上手指南
    分布式事务专题
    mysql 慢查询日志分析与使用
  • 原文地址:https://www.cnblogs.com/chadinblog/p/5831484.html
Copyright © 2020-2023  润新知