• [Bzoj1051][HAOI2006]受欢迎的牛(tarjan)


    题目链接:https://www.lydsy.com/JudgeOnline/problem.php?id=1051

    由题意可知,被所有牛仰慕的牛之间也互相仰慕,则最后的答案一定是唯一的强连通分量,如图:

    且这个强连通分量出度为0。

    所以用tarjan缩环,然后在判断出度为0的是否有且仅有一个点。

     1 #include<bits/stdc++.h>
     2 using namespace std;
     3 typedef long long ll;
     4 const int maxn = 10010;
     5 struct node {
     6     int e, next;
     7 }edge[50010];
     8 int head[maxn * 20], len;
     9 void add(int s, int e) {
    10     edge[++len].e = e;
    11     edge[len].next = head[s];
    12     head[s] = len;
    13 }
    14 int color[maxn], dfn[maxn], low[maxn], vis[maxn];
    15 int out[maxn];
    16 int num[maxn];
    17 int dfsnum, ansnum, top;
    18 stack<int>q;
    19 void tarjan(int x) {
    20     dfn[x] = low[x] = ++dfsnum;
    21     vis[x] = 1;
    22     q.push(x);
    23     for (int i = head[x]; i; i = edge[i].next) {
    24         int y = edge[i].e;
    25         if (!dfn[y]) {
    26             tarjan(y);
    27             low[x] = min(low[x], low[y]);
    28         }
    29         else if (vis[y])
    30             low[x] = min(low[x], dfn[y]);
    31     }
    32     if (low[x] == dfn[x]) {
    33         ansnum++;
    34         int y;
    35         do {
    36             y = q.top();
    37             q.pop();
    38             color[y] = ansnum;
    39             num[ansnum]++;
    40             vis[y] = 0;
    41         } while (x != y);
    42     }
    43 }
    44 int main() {
    45     int n, m, x, y;
    46     scanf("%d%d", &n, &m);
    47     for (int i = 1; i <= m; i++) {
    48         scanf("%d%d", &x, &y);
    49         add(x, y);
    50     }
    51     for (int i = 1; i <= n; i++)
    52         if (!dfn[i])
    53             tarjan(i);
    54     for (int x = 1; x <= n; x++) {
    55         for (int i = head[x]; i; i = edge[i].next) {
    56             int y = edge[i].e;
    57             if (color[x] != color[y])
    58                 out[color[x]]++;
    59         }
    60     }
    61     int ans = 0, f = 0;
    62     for (int i = 1; i <= ansnum; i++)
    63         if (out[i] == 0)ans = num[i], f++;
    64     if (f == 1)
    65         printf("%d
    ", ans);
    66     else
    67         printf("0
    ");
    68 }
  • 相关阅读:
    Java 环境变量配置
    C# 怎样判断一个字符串的编码类型
    ASP.NET MVC Razor视图引擎基础语法
    Silverlight 访问外部程序
    Silverlight 换肤的实现
    Silverlight初始动画 加载动画
    Silverlight App中线程同步
    .net反射简介
    FLASH 中文显示乱码
    [原创]开源Word读写组件DocX,通过word模板,导出用户简历使用示例
  • 原文地址:https://www.cnblogs.com/sainsist/p/11116600.html
Copyright © 2020-2023  润新知