缩点练习

洛谷 P3387 【模板】缩点

缩点

解题思路:

都说是模板了...先缩点把有环图转换成DAG

然后拓扑排序即可

#include <bits/stdc++.h>
using namespace std;
/* freopen("k.in", "r", stdin);
freopen("k.out", "w", stdout); */
//clock_t c1 = clock();
//std::cerr << "Time:" << clock() - c1 <<"ms" << std::endl;
//#pragma comment(linker, "/STACK:1024000000,1024000000")
#define de(a) cout << #a << " = " << a << endl
#define rep(i, a, n) for (int i = a; i <= n; i++)
#define per(i, a, n) for (int i = n; i >= a; i--)
typedef long long ll;
typedef unsigned long long ull;
typedef pair<int, int> PII;
typedef pair<double, double> PDD;
typedef vector<int, int> VII;
#define inf 0x3f3f3f3f
const ll INF = 0x3f3f3f3f3f3f3f3f;
const ll MAXN = 5e5 + 7;
const ll MAXM = 1e6 + 7;
const ll MOD = 1e9 + 7;
const double eps = 1e-6;
const double pi = acos(-1.0);
int head[MAXN], head1[MAXN];
int in[MAXN];
int n, m;
int vis[MAXN];
int dfn[MAXN], low[MAXN], dep;
int sta[MAXN], top = -1;
int tot; //强联通分量编号
int dis[MAXN];
int p[MAXN];
int num[MAXN];
struct Edge
{
int u, v, Next;
Edge(int _u = 0, int _v = 0, int _Next = 0) { u = _u, v = _v, Next = _Next; }
} e[MAXN << 1], ed[MAXN << 1];
int cnt = -1;
void add(int u, int v)
{
e[++cnt].v = v;
e[cnt].u = u;
e[cnt].Next = head[u];
head[u] = cnt;
}
void tarjan(int now)
{
dfn[now] = low[now] = ++dep;
sta[++top] = now;
vis[now] = 1;
for (int i = head[now]; ~i; i = e[i].Next)
{
int v = e[i].v;
if (!dfn[v])
{
tarjan(v);
low[now] = min(low[now], low[v]);
}
else if (vis[v])
low[now] = min(low[now], low[v]);
}
if (dfn[now] == low[now])
{
++tot;
while (sta[top] != now)
{
vis[sta[top]] = 0;
num[sta[top]] = tot;
dis[tot] += p[sta[top--]];
}
vis[sta[top]] = 0;
dis[tot] += p[sta[top]];
num[sta[top--]] = tot;
}
}
int dp[MAXN];
int topo()
{
queue<int> q;
int ans = -inf;
int k = 0;
for (int i = 1; i <= tot; i++)
if (!in[i])
q.push(i), dp[i] = dis[i];
while (!q.empty())
{
int now = q.front();
q.pop();
k++;
for (int i = head1[now]; ~i; i = ed[i].Next)
{
int v = ed[i].v;
in[v]--;
dp[v] = max(dp[v], dp[now] + dis[v]);
if (!in[v])
q.push(v);
}
}
for (int i = 1; i <= tot; i++)
ans = max(ans, dp[i]);
return ans;
}
int main()
{
memset(head, -1, sizeof(head));
memset(head1, -1, sizeof(head1));
scanf("%d%d", &n, &m);
for (int i = 1; i <= n; i++)
scanf("%d", &p[i]);
for (int i = 0; i < m; i++)
{
int u, v;
scanf("%d%d", &u, &v);
add(u, v);
}
for (int i = 1; i <= n; i++)
if (!dfn[i])
tarjan(i);
cnt = -1;
for (int i = 0; i < m; i++)
{
int x = e[i].u, y = e[i].v;
if (num[x] != num[y]) //不在一个强连通分量
{
int u = num[x], v = num[y];
ed[++cnt].u = u;
ed[cnt].v = v;
ed[cnt].Next = head1[u];
head1[u] = cnt;
in[v]++;
}
}
printf("%d\n", topo());
return 0;
}

poj 2196 Popular Cows

Popular Cows

Every cow's dream is to become the most popular cow in the herd. In a herd of N (1 <= N <= 10,000) cows, you are given up to M (1 <= M <= 50,000) ordered pairs of the form (A, B) that tell you that cow A thinks that cow B is popular. Since popularity is transitive, if A thinks B is popular and B thinks C is popular, then A will also think that C is

popular, even if this is not explicitly specified by an ordered pair in the input. Your task is to compute the number of cows that are considered popular by every other cow.

Input

  • Line 1: Two space-separated integers, N and M

  • Lines 2..1+M: Two space-separated numbers A and B, meaning that A thinks B is popular.

    Output

  • Line 1: A single integer that is the number of cows who are considered popular by every other cow.

Sample Input

3 3

1 2

2 1

2 3

Sample Output

1

解题思路:

将原图缩点之后重新建图,那么被所有牛崇拜的牛必然在出度为0的一个强连通分量内,如果有一个以上出度为0的强联通分量,则说明不存在被所有牛崇拜的牛,如果出度为0的强联通分量为1那么直接输出该强联通分量内牛的数量即可

#include <algorithm>
#include <cstdio>
#include <cmath>
#include <cstring>
#include <iostream>
#include <cstdlib>
#include <set>
#include <vector>
#include <cctype>
#include <iomanip>
#include <sstream>
#include <climits>
#include <queue>
#include <stack>
using namespace std;
/* freopen("k.in", "r", stdin);
freopen("k.out", "w", stdout); */
//clock_t c1 = clock();
//std::cerr << "Time:" << clock() - c1 <<"ms" << std::endl;
//#pragma comment(linker, "/STACK:1024000000,1024000000")
#define de(a) cout << #a << " = " << a << endl
#define rep(i, a, n) for (int i = a; i <= n; i++)
#define per(i, a, n) for (int i = n; i >= a; i--)
typedef long long ll;
typedef unsigned long long ull;
typedef pair<int, int> PII;
typedef pair<double, double> PDD;
typedef vector<int, int> VII;
#define inf 0x3f3f3f3f
const ll INF = 0x3f3f3f3f3f3f3f3f;
const ll MAXN = 5e5 + 7;
const ll MAXM = 1e6 + 7;
const ll MOD = 1e9 + 7;
const double eps = 1e-6;
const double pi = acos(-1.0);
int n, m;
int head[MAXN], dis[MAXN];
int in[MAXN];
struct Edge
{
int u, v, Next;
Edge(int _u = 0, int _v = 0, int _Next = 0) { u = _u, v = _v, Next = _Next; }
} e[MAXN], ed[MAXN];
int cnt = -1;
void add(int u, int v)
{
e[++cnt].u = u;
e[cnt].v = v;
e[cnt].Next = head[u];
head[u] = cnt;
}
int dfn[MAXN], low[MAXN], dep;
int tot;
int sta[MAXN], top = -1, vis[MAXN];
int num[MAXN];
void tarjan(int now)
{
dfn[now] = low[now] = ++dep;
sta[++top] = now;
vis[now] = 1;
for (int i = head[now]; ~i; i = e[i].Next)
{
int v = e[i].v;
if (!dfn[v])
{
tarjan(v);
low[now] = min(low[now], low[v]);
}
else if (vis[v])
low[now] = min(low[now], low[v]);
}
if (dfn[now] == low[now])
{
tot++;
while (sta[top] != now)
{
num[sta[top]] = tot;
dis[tot]++;
vis[sta[top--]] = 0;
}
vis[sta[top]] = 0;
dis[tot]++;
num[sta[top--]] = tot;
}
}
int main()
{
memset(head, -1, sizeof(head));
scanf("%d%d", &n, &m);
for (int i = 0; i < m; i++)
{
int u, v;
scanf("%d%d", &u, &v);
add(u, v);
}
for (int i = 1; i <= n; i++)
if (!dfn[i])
tarjan(i);
//重新建图
for (int i = 0; i < m; i++)
{
int x = e[i].u, y = e[i].v;
if (num[x] != num[y])
{
int u = num[x], v = num[y];
in[u]++; //这里是出度....
}
}
int tt = 0;
int ans = 0;
for (int i = 1; i <= tot; i++)
{
if (!in[i])
{
tt++;
ans = max(ans, dis[i]);
}
}
if (tt > 1)
ans = 0;
printf("%d\n", ans);
return 0;
}
/*
7 8
1 2
2 4
4 6
6 7
7 6
1 3
3 5
5 6 */

tarjan缩点练习 洛谷P3387 【模板】缩点+poj 2186 Popular Cows的更多相关文章

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

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

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

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

  3. poj 2186 Popular Cows【tarjan求scc个数&&缩点】【求一个图中可以到达其余所有任意点的点的个数】

    Popular Cows Time Limit: 2000MS   Memory Limit: 65536K Total Submissions: 27698   Accepted: 11148 De ...

  4. POJ 2186 Popular Cows(Targin缩点)

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

  5. poj 2186 Popular Cows tarjan

    Popular Cows Description Every cow's dream is to become the most popular cow in the herd. In a herd ...

  6. POJ 2186 Popular Cows tarjan缩点算法

    题意:给出一个有向图代表牛和牛喜欢的关系,且喜欢关系具有传递性,求出能被所有牛喜欢的牛的总数(除了它自己以外的牛,或者它很自恋). 思路:这个的难处在于这是一个有环的图,对此我们可以使用tarjan算 ...

  7. POJ 2186 Popular Cows(强连通分量缩点)

    题目链接:http://poj.org/problem?id=2186 题目意思大概是:给定N(N<=10000)个点和M(M<=50000)条有向边,求有多少个“受欢迎的点”.所谓的“受 ...

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

    题意: 有一群牛, a会认为b很帅, 且这种认为是传递的. 问有多少头牛被其他所有牛认为很帅~ 思路: 关键就是分析出缩点之后的有向树只能有一个叶子节点(出度为0). 做法就是Tarjan之后缩点统计 ...

  9. poj 2186 Popular Cows :求能被有多少点是能被所有点到达的点 tarjan O(E)

    /** problem: http://poj.org/problem?id=2186 当出度为0的点(可能是缩点后的点)只有一个时就存在被所有牛崇拜的牛 因为如果存在有两个及以上出度为0的点的话,他 ...

随机推荐

  1. Java面向对象程序设计第14章3-8和第15章6

    Java面向对象程序设计第14章3-8和第15章6 3.完成下面方法中的代码,要求建立一个缓冲区,将字节输入流中的内容转为字符串. import java.io.*; public class tes ...

  2. 如何看Crash 文件

    如何查看崩溃日志 好了,获得是人类可读语言的崩溃日志后,或者是从别人手机到处崩溃日志后,下一步就是查看了.下面就正对一个程序猿该如何看稍微说说. 崩溃日志头     1 2 3 4 5 6 7 8 9 ...

  3. DEVOPS技术实践_13:使用Jenkins持续传送设计-CD基础

    1. 分支策略 持续集成中使用的分支策略包括以下三个: The master branch The integration branch The feature branch 而CD只在Integra ...

  4. 还看不懂同事代码?快来补一波 Java 7 语法特性

    前言 Java 平台自出现到目前为止,已经 20 多个年头了,这 20 多年间 Java 也一直作为最流行的程序设计语言之一,不断面临着其他新兴编程语言的挑战与冲击.Java 语言是一种静态强类型语言 ...

  5. Eclipse配置运行内存

    对于一些大的项目,运行时等待过长可能出现内存溢出现象,需要重新配置IDE运行内存大小,如下: 1.配置Eclipse.ini 如图再改大点: -Xms512m-Xmx512m 2.JDK内存扩大 Wc ...

  6. 从零开始学asyncio(上)

    这篇文章主要是介绍生成器和IO多路复用机制, 算是学习asyncio需要的预备知识. 这个系列还有另外两篇文章: 从零开始学asyncio(中) 从零开始学asyncio(下) 一. 简单爬虫实例 首 ...

  7. 深入理解协程(三):async/await实现异步协程

    原创不易,转载请联系作者 深入理解协程分为三部分进行讲解: 协程的引入 yield from实现异步协程 async/await实现异步协程 本篇为深入理解协程系列文章的最后一篇. 从本篇你将了解到: ...

  8. 案例分析丨H&M用设计冲刺将App研发周期缩短为6个月

    案例背景 H&M是一家来自瑞典的时装公司,1947年成立.截至2018年6月,H&M 分店遍布全球 68 个国家和地区,分店数目为 4338 间. 作为快速服装生产商,H&M的 ...

  9. Spring-cloud微服务实战【一】:微服务的概念与演进过程

    本文是一个系列文章,主要讲述使用spring-cloud进行微服务开发的实战.在开始之前,我们先说一下从传统的单一部署架构到微服务的发展过程,以便让童鞋们更好的理解微服务的概念与演进过程. 1.单体架 ...

  10. DFS——深度优先搜索的一般格式

    DFS是一种深度优先的搜索思想,运用递归完成搜索,本质上也算是穷举思想的一类,可以通过剪枝进行优化. DFS的核心是回溯和递归, 如果以迷宫为例,一般会指定走各个方向的顺序(例如先左再上再右再下).从 ...