http://poj.org/problem?id=2186

首先求出所有的强连通分量,分好块。然后对于每一个强连通分量,都标记下他们的出度。那么只有出度是0 的块才有可能是答案,为什么呢?因为既然你有了出度,那么就是指向了另外一个块,那么你就不能指望那个块也指向你了,因为这样会形成环,所以肯定有一个块的cow不支持你,所以你这个块就不会是popular cow

那么就有两种情况,

①、出度是0的块的个数是1个,那么就是唯一的答案。

②、出度是0的快的个数有多个,那么答案是0, 因为至少也有一个块不支持你。

不会存在出度为0的个数是0这样的,起码都会有一个块出度是0.

记得清空各种数组。

#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <cmath>
#include <algorithm>
#include <assert.h>
#define IOS ios::sync_with_stdio(false)
using namespace std;
#define inf (0x3f3f3f3f)
typedef long long int LL; #include <iostream>
#include <sstream>
#include <vector>
#include <set>
#include <map>
#include <queue>
#include <string>
#include <bitset>
const int maxn = 1e5 + ;
struct Edge {
int u, v, w, tonext;
}e[maxn * ];
int first[maxn], num;
void addEdge(int u, int v) {
++num;
e[num].u = u, e[num].v = v;
e[num].tonext = first[u];
first[u] = num;
}
int DFN[maxn], low[maxn], st[maxn], top, when, vis[maxn];
int id[maxn], toSelId, out[maxn], sum[maxn];
void tarjan(int cur, int fa) {
DFN[cur] = low[cur] = ++when; // 时间戳
st[++top] = cur; //进栈
vis[cur] = true;
for (int i = first[cur]; i; i = e[i].tonext) {
int v = e[i].v;
if (!DFN[v]) { //没访问过
tarjan(v, cur);
low[cur] = min(low[cur], low[v]);
} else if (vis[v]) { // 访问过,而且还在栈里
low[cur] = min(low[cur], DFN[v]);
}
}
if (low[cur] == DFN[cur]) { //这个是强连通分量的根节点。
++toSelId;
do {
id[st[top]] = toSelId;
sum[toSelId]++;
// printf("%d ", st[top]);
vis[st[top]] = false;
top--;
} while (cur != st[top + ]);
// printf("\n");
}
}
void sloveTarjan(int n) { //防止开始枚举的节点没有出边,暴力枚举每一个节点
memset(low, , sizeof low);
memset(DFN, , sizeof DFN);
memset(vis, , sizeof vis);
memset(id, , sizeof id);
memset(out, , sizeof out);
memset(sum, , sizeof sum);
top = when = toSelId = ;
for (int i = ; i <= n; ++i) {
if (!DFN[i]) {
tarjan(i, i);
}
}
}
int n, m;
void work() {
// int n, m;
// scanf("%d%d", &n, &m);
num = ;
memset(first, , sizeof first);
for (int i = ; i <= m; ++i) {
int u, v;
scanf("%d%d", &u, &v);
addEdge(u, v);
}
sloveTarjan(n);
for (int i = ; i <= n; ++i) {
for (int j = first[i]; j; j = e[j].tonext) {
int v = e[j].v;
if (id[i] == id[v]) continue;
out[id[i]]++;
}
}
int has = ;
int ans;
for (int i = ; i <= toSelId; ++i) {
if (out[i] == ) {
has++;
ans = i;
}
}
if (has >= ) {
printf("0\n");
// cout << 0 << endl;
return;
}
printf("%d\n", sum[ans]);
// cout << sum[ans] << endl;
}
int main() {
#ifdef local
freopen("data.txt", "r", stdin);
// freopen("data.txt", "w", stdout);
#endif
while (scanf("%d%d", &n, &m) != EOF) work();
return ;
}

POJ - 2186  Popular Cows tarjain模板题的更多相关文章

  1. 强连通分量分解 Kosaraju算法 (poj 2186 Popular Cows)

    poj 2186 Popular Cows 题意: 有N头牛, 给出M对关系, 如(1,2)代表1欢迎2, 关系是单向的且能够传递, 即1欢迎2不代表2欢迎1, 可是假设2也欢迎3那么1也欢迎3. 求 ...

  2. tarjan缩点练习 洛谷P3387 【模板】缩点+poj 2186 Popular Cows

    缩点练习 洛谷 P3387 [模板]缩点 缩点 解题思路: 都说是模板了...先缩点把有环图转换成DAG 然后拓扑排序即可 #include <bits/stdc++.h> using n ...

  3. poj 2186 Popular Cows (强连通分量+缩点)

    http://poj.org/problem?id=2186 Popular Cows Time Limit: 2000MS   Memory Limit: 65536K Total Submissi ...

  4. POJ 2186 Popular Cows (强联通)

    id=2186">http://poj.org/problem? id=2186 Popular Cows Time Limit: 2000MS   Memory Limit: 655 ...

  5. poj 2186 Popular Cows 【强连通分量Tarjan算法 + 树问题】

    题目地址:http://poj.org/problem?id=2186 Popular Cows Time Limit: 2000MS   Memory Limit: 65536K Total Sub ...

  6. POJ 2186:Popular Cows Tarjan模板题

    Popular Cows Time Limit: 2000MS   Memory Limit: 65536K Total Submissions: 25945   Accepted: 10612 De ...

  7. poj 2186 Popular Cows

    Popular Cows Time Limit: 2000MS   Memory Limit: 65536K Total Submissions: 29908   Accepted: 12131 De ...

  8. [强连通分量] POJ 2186 Popular Cows

    Popular Cows Time Limit: 2000MS   Memory Limit: 65536K Total Submissions: 31815   Accepted: 12927 De ...

  9. POJ 2186 Popular Cows(Targin缩点)

    传送门 Popular Cows Time Limit: 2000MS   Memory Limit: 65536K Total Submissions: 31808   Accepted: 1292 ...

随机推荐

  1. codeforces 463A Caisa and Sugar 解题报告

    题目链接:http://codeforces.com/problemset/problem/463/A 题目意思:某个人有 s dollar的钱,有 n 种类型的糖果,第 i 种糖果的价值为 xi d ...

  2. js Date 函数方法及日期计算

    js Date 函数方法 var myDate = new Date(); myDate.getYear(); //获取当前年份(2位) myDate.getFullYear(); //获取完整的年份 ...

  3. python 基础之第十一天(面向对象)

    #############面向对象##################### 类: In [1]: class MyClass(object): ##用class定义一个类 ...: def psta ...

  4. AQS共享锁应用之Semaphore原理

    我们调用Semaphore方法时,其实是在间接调用其内部类或AQS方法执行的.Semaphore类结构与ReetrantLock类相似,内部类Sync继承自AQS,然后其子类FairSync和NoFa ...

  5. firewalld·使用方法示例

    firewalld使用方法示例 # systemctl start firewalld # 启动, # systemctl enable firewalld # 开机启动 # systemctl st ...

  6. 回味经典——uboot1.1.6 之 第二阶段 第三阶段

    转自:http://blog.csdn.net/lizuobin2/article/details/52061530 上篇文章说到,再清 BSS 段之后,CPU 跳转到 sdram 里的 start_ ...

  7. 关于git被误删除的分支还原问题

    在开发过程中, 有可能会将正在开发的本地分支误删, 本地分支被删除时, 如果已经将本地分支的变更推送到了远端, 还没有问题, 如果被删除的本地分支只提交了没有推送到远端, 就悲剧了, 相当于在你上一次 ...

  8. Ubuntu环境下gedit以及vim的一些个简单配置

    Gedit的配置: 参见 http://www.cnblogs.com/csulennon/p/4198054.html Gedit插件安装 Gedit快捷键 参见我的博客 添加快捷键 Ctrl + ...

  9. Python 之IO模型

    阻塞IO模型:以前写的套接字通信都是阻塞型的.通过并发提高效率 非阻塞IO模型: from socket import * # 并不推荐使用,一是消耗cpu资源,二是会响应延迟 server = so ...

  10. 【HBase】HBase笔记:HBase的Region机制

    HBase 的机制里包含了许多优秀的算法,如 Region 定位.Region 分配.Region Server的上线和下线.Master 的上线和下线.在谈到这些之前,先把 HBase 的基本架构里 ...