tarjan缩点练习 洛谷P3387 【模板】缩点+poj 2186 Popular Cows
缩点练习
洛谷 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.
OutputLine 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的更多相关文章
- poj 2186 Popular Cows (强连通分量+缩点)
http://poj.org/problem?id=2186 Popular Cows Time Limit: 2000MS Memory Limit: 65536K Total Submissi ...
- poj 2186 Popular Cows 【强连通分量Tarjan算法 + 树问题】
题目地址:http://poj.org/problem?id=2186 Popular Cows Time Limit: 2000MS Memory Limit: 65536K Total Sub ...
- poj 2186 Popular Cows【tarjan求scc个数&&缩点】【求一个图中可以到达其余所有任意点的点的个数】
Popular Cows Time Limit: 2000MS Memory Limit: 65536K Total Submissions: 27698 Accepted: 11148 De ...
- POJ 2186 Popular Cows(Targin缩点)
传送门 Popular Cows Time Limit: 2000MS Memory Limit: 65536K Total Submissions: 31808 Accepted: 1292 ...
- 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 ...
- POJ 2186 Popular Cows tarjan缩点算法
题意:给出一个有向图代表牛和牛喜欢的关系,且喜欢关系具有传递性,求出能被所有牛喜欢的牛的总数(除了它自己以外的牛,或者它很自恋). 思路:这个的难处在于这是一个有环的图,对此我们可以使用tarjan算 ...
- POJ 2186 Popular Cows(强连通分量缩点)
题目链接:http://poj.org/problem?id=2186 题目意思大概是:给定N(N<=10000)个点和M(M<=50000)条有向边,求有多少个“受欢迎的点”.所谓的“受 ...
- [poj 2186]Popular Cows[Tarjan强连通分量]
题意: 有一群牛, a会认为b很帅, 且这种认为是传递的. 问有多少头牛被其他所有牛认为很帅~ 思路: 关键就是分析出缩点之后的有向树只能有一个叶子节点(出度为0). 做法就是Tarjan之后缩点统计 ...
- poj 2186 Popular Cows :求能被有多少点是能被所有点到达的点 tarjan O(E)
/** problem: http://poj.org/problem?id=2186 当出度为0的点(可能是缩点后的点)只有一个时就存在被所有牛崇拜的牛 因为如果存在有两个及以上出度为0的点的话,他 ...
随机推荐
- 第四阶段:1.从零打造一款社区web产品
---恢复内容开始--- 熟人关系:微信 陌生人关系:微博 1.把各种竞品罗列起来形成一个分析池.分析其目标用户是哪些.这些产品满足了用户什么需求.可以从时间角度分析趋势.针对每一类竞品画一个商业模式 ...
- centos安装pip,zipimport.ZipImportError报错
安装pip下载pip安装包wget https://bootstrap.pypa.io/get-pip.py 执行以下报错 python get-pip.py ##报错内容(zipimport.Zip ...
- Alpha阶段中间产物提交入口
此作业要求参见:https://edu.cnblogs.com/campus/nenu/2019fall/homework/9865 git地址:https://e.coding.net/Eustia ...
- 从零开始のcocos2dx生活(十一)TableView
目录 简述 主要变量 主要方法 setVerticalFillOrder reloadData cellAtIndex updateCellAtIndex insertCellAtIndex remo ...
- $Noip2018/Luogu5021$ 赛道修建 二分+树形
$Luogu$ $Sol$ 一直以为是每个点只能经过一次没想到居然是每条边只能经过一次$....$ 首先其实这题$55$分的部分分真的很好写啊,分别是链,数的直径和菊花图,这里就不详细说了. 使得修建 ...
- Spring Security入门(基于SSM环境配置)
一.前期准备 配置SSM环境 二.不使用数据库进行权限控制 配置好SSM环境以后,配置SpringSecurity环境 添加security依赖 <dependency> <gr ...
- LibreOJ6279. 数列分块入门 3 题解
题目链接:https://loj.ac/problem/6279 题目描述 给出一个长为 \(n\) 的数列,以及 \(n\) 个操作,操作涉及区间加法,询问区间内小于某个值 \(x\) 的前驱(比其 ...
- 无聊读论文:视觉注意力模型RARE2012
Riche, N., Mancas, M., Duvinage, M., Mibulumukini, M., Gosselin, B., & Dutoit, T. (2013). RARE20 ...
- Spring Data JPA使用findAllOrderBy时踩的坑
Spring Data JPA使用findAllOrderBy时踩的坑 按照以往的编程经验,我的写法是这样的: List<ActivityEntity> findAllOrderByWis ...
- 爆破linux密码 $6$3uwqC9JI$d9iPRmTDAoXs/IbsplxS3iyeErHqw7fUycacXNHyZk1UCSwFEydl515/zXN7OEwHnyUaqYcNG
#!/usr/bin/env python # -*- coding:UTF-8 -*- import crypt import sys # 哈希密码的前两位就是盐的前两位,这里我们假设盐只有两位. ...