缩点练习

洛谷 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. 007.MFC_ComboBox_ListBox

    组合框.列表框 组合框的封装类:CComboBox 列表框的封装类:CListBox 一.创建名为ComboAndList的MFC工程,按照下图添加组件 修改static text Caption属性 ...

  2. 第二阶段:2.商业需求文档MRD:1.M版本管理

    版本管理的例子.V=Version.注意大中小版本的区分.V1.2.2 第一个数字1就是大版本 中间的2就是中版本 末尾的2就是小版本.大版本就是方向的变更,比如我的用户之前主要是面向男性,现在要面向 ...

  3. 基于 Apache APISIX 的下一代微服务架构

    2019 年 12 月 14 日,又拍云联合 Apache APISIX 社区举办 API 网关与高性能服务最佳实践丨Open Talk 广州站活动,Apache APISIX PPMC 温铭做了题为 ...

  4. CentOS 下 maven 安装

    获取maven安装包 wget http://mirrors.hust.edu.cn/apache/maven/maven-3/3.2.5/binaries/apache-maven-3.2.5-bi ...

  5. C语言之while循环

    while循环能做什么??? 先来个概念格式,while循环的一般形式为: while(表达式){ 语句块 } 意思是,先计算"表达式"的值,当值为真(非0)时, 执行" ...

  6. k8s-自动安装

    操作环境: centos7.3 node102-master-192.168.100.102 node103-node1-192.168.100.103 node104-node2-192.168.1 ...

  7. WPF 添加提示动画

    下面放一张效果图: 那么具体是怎么实现呢: 前端XAML中: <Image Source="/Images/tips.png" HorizontalAlignment=&qu ...

  8. 2018湘潭邀请赛 AFK题解 其他待补...

    A.HDU6276:Easy h-index Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/O ...

  9. swiper如何禁止左右箭头切换

    swiper做项目时,需求 带着左右两边的箭头, 场景1:swiper自动切换,此时左右箭头点击时不能切换   场景2:swiper手动切换,左右箭头可以实现切换,通过翻阅api 终于找到 <s ...

  10. linux下文件解压缩中文乱码问题的解决

    将带中文文件名的压缩文件上传到服务器,使用unzip解压后,文件名乱码: 临时解决方法: 通过unzip行命令解压,指定字符集unzip -O CP936 xxx.zip (用GBK, GB18030 ...