Tarjan缩点

Tarjan缩点

或许更好的阅读体验

P3387 【模板】缩点

思路

既然时缩点的模板,那么缩点自然少不了了,缩点后我们的到新的有向无环图,然后再利用这个无环图去找一条最大权值的路径,路径和即为答案。

我们改如何选取起点来避免不必要的计算,假设存在一条路径,我们的最大值一定时从起点开始的,所以我们选取所有的缩点以后入度为零的点去bfs,然后不断更新最大路径值。

代码

#include <bits/stdc++.h>using namespace std;typedef long long ll;inline ll read() {ll f = 1, x = 0;char c = getchar();while(c > '9' || c < '0') {if(c == '-')    f = -1;c = getchar();}while(c >= '0' && c <= '9') {x = (x << 1) + (x << 3) + (c ^ 48);c = getchar();}return f * x;
}const int N1 = 1e4 + 10, N2 = 1e5 + 10;int head[N1], to[N2], nex[N2], cnt = 1;
int dfn[N1], low[N1], visit[N1], scc[N1], point[N1], value[N1], n, m, tot, sum;
int x[N2], y[N2];
int stk[N1], top;int head1[N1], to1[N2], nex1[N2], cnt1 = 1;
int in[N1];void tarjan(int rt) {dfn[rt] = low[rt] = ++tot;visit[rt] = 1;stk[++top] = rt;for(int i = head[rt]; i; i = nex[i]) {if(!dfn[to[i]]) {tarjan(to[i]);low[rt] = min(low[rt], low[to[i]]);}else if(visit[to[i]]) {low[rt] = min(low[rt], dfn[to[i]]);}}if(dfn[rt] == low[rt]) {sum++;do {visit[stk[top]] = 0;scc[stk[top]] = sum;value[sum] += point[stk[top]];top--;}while(stk[top + 1] != rt);}
}void add(int x, int y) {to[cnt] = y;nex[cnt] = head[x];head[x] = cnt++;
}void bfs() {queue<pair<int, int>> q;for(int i = 1; i <= sum; i++)if(in[i] == 0)q.push(make_pair(i, value[i]));int ans = 0;while(!q.empty()) {int temp = q.front().first;ans = max(ans, q.front().second);for(int i = head1[temp]; i; i = nex1[i])q.push(make_pair(to1[i], q.front().second + value[to1[i]]));q.pop();}printf("%d\n", ans);
}int main() {// freopen("in.txt", "r", stdin);n = read(), m = read();for(int i = 1; i <= n; i++)point[i] = read();for(int i = 1; i <= m; i++) {x[i] = read(), y[i] = read();add(x[i], y[i]);}for(int i = 1; i <= n; i++)if(!dfn[i])tarjan(i);for(int i = 1; i <= m; i++)//缩点后重新建边。if(scc[x[i]] != scc[y[i]]) {in[scc[y[i]]]++;to1[cnt1] = scc[y[i]];nex1[cnt1] = head1[scc[x[i]]];head1[scc[x[i]]] = cnt1++;}bfs();return 0;
}

Popular Cows

思路

显然是一道缩点的题目,缩点完后,我们可以知道如果一个强连通分量的出度为零,并且只有一个强连通分量的初读为零,那么缩点后的图一定时联通的,这个时候出度为零的强连通分量重的点的个数就是我们要求的答案。

代码

// #include <bits/stdc++.h>
#include <iostream>
#include <cstdio>
#include <algorithm>
#include <cstring>
#include <stdlib.h>
#include <queue>
#include <stack>
#include <vector>
#include <bitset>using namespace std;typedef long long ll;inline ll read() {ll f = 1, x = 0;char c = getchar();while(c > '9' || c < '0') {if(c == '-')    f = -1;c = getchar();}while(c >= '0' && c <= '9') {x = (x << 1) + (x << 3) + (c ^ 48);c = getchar();}return f * x;
}const int N1 = 1e4 + 10, N2 = 5e4 + 10;int head[N1], to[N2], nex[N2], cnt = 1;
int visit[N1], dfn[N1], low[N1], scc[N1], sz[N1], n, m, tot, sum;
int x[N2], y[N2], out[N1];
int stk[N1], top;void add(int x, int y) {to[cnt] = y;nex[cnt] = head[x];head[x] = cnt++;
}void tarjan(int rt) {visit[rt] = 1, stk[++top] = rt;dfn[rt] = low[rt] = ++tot;for(int i = head[rt]; i; i = nex[i]) {if(!dfn[to[i]]) {tarjan(to[i]);low[rt] = min(low[rt], low[to[i]]);}else if(visit[to[i]])low[rt] = min(low[rt], dfn[to[i]]);}if(dfn[rt] == low[rt]) {sum++;do {scc[stk[top]] = sum;sz[sum]++;visit[stk[top]] = 0;top--;}while(rt != stk[top + 1]);}
}int main() {// freopen("in.txt", "r", stdin);while(scanf("%d %d", &n, &m) != EOF) {for(int i = 1; i <= n; i++)head[i] = visit[i] = sz[i] = out[i] = dfn[i] = 0;cnt = 1, tot = sum = top = 0;for(int i = 1; i <= m; i++) {x[i] = read(), y[i] = read();add(x[i], y[i]);}for(int i = 1; i <= n; i++)if(!dfn[i])tarjan(i);// puts("okkkkk");for(int i = 1; i <= m; i++)if(scc[x[i]] != scc[y[i]])out[scc[x[i]]]++;int num = 0, ans = 0;for(int i = 1; i <= sum; i++)if(out[i] == 0) {ans = sz[i];num++;}if(num != 1)    puts("0");else    printf("%d\n", ans);}return 0;
}

Bomb

思路

容易想到爆炸就是一个传递的图,当爆炸形成一个环的时候,明显可以进行缩点操作,所以当我们进行完缩点之后,我们只要统计剩余的点中入度为零的点就行,同时我们需要的花费就是这些点所在的联通分量中的花费最小的点。

代码

#include <bits/stdc++.h>using namespace std;typedef long long ll;ll read() {ll f = 1, x = 0;char c = getchar();while(c < '0' || c > '9') {if(c == '-')    f = -1;c = getchar();}while(c >= '0' && c <= '9') {x = (x << 1) + (x << 3) + (c ^ 48);c = getchar();}return f * x;
}const ll INF = 0x3f3f3f3f3f3f3f3f;
const int N1 = 1e3 + 10, N2 = 1e6 + 10;int head[N1], to[N2], nex[N2], cnt;
int visit[N1], dfn[N1], low[N1], scc[N1], n, sum, tot;
int stk[N1], in[N1], top;
ll cost[N1];struct point {ll x, y, c, r;void input() {x = read(), y = read(), r = read(), c = read();}
}a[N1];ll dis(point a, point b) {return (a.x - b.x) * (a.x - b.x) + (a.y - b.y) * (a.y - b.y);
}void add(int x, int y) {to[cnt] = y;nex[cnt] = head[x];head[x] = cnt++;
}void tarjan(int rt) {dfn[rt] = low[rt] = ++tot;stk[++top] = rt;visit[rt] = 1;for(int i = head[rt]; i; i = nex[i]) {if(!dfn[to[i]]) {tarjan(to[i]);low[rt] = min(low[rt], low[to[i]]);}else if(visit[to[i]])low[rt] = min(low[rt], dfn[to[i]]);}if(dfn[rt] == low[rt]) {sum++;do {scc[stk[top]] = sum;cost[sum] = min(cost[sum], a[stk[top]].c);visit[top[stk]] = 0;top--;}while(stk[top + 1] != rt);}
}int main() {// freopen("in.txt", "r", stdin);int t = read();for(int cas = 1; cas <= t; cas++) {n = read();for(int i = 1; i <= n; i++) {head[i] = visit[i] = dfn[i] = low[i] = scc[i] = in[i] = 0;cost[i] = INF;a[i].input();}tot = sum = top = 0, cnt = 1;for(int i = 1; i <= n; i++)for(int j = i + 1; j <= n; j++) {ll d = dis(a[i], a[j]);if(d <= a[i].r * a[i].r)add(i, j);if(d <= a[j].r * a[j].r)add(j, i);}for(int i = 1; i <= n; i++)if(!dfn[i])tarjan(i);for(int i = 1; i <= n; i++)for(int j = head[i]; j; j = nex[j])if(scc[i] != scc[to[j]])in[scc[to[j]]]++;ll ans = 0;for(int i = 1; i <= sum; i++)if(in[i] == 0)ans += cost[i];printf("Case #%d: %lld\n", cas, ans);}return 0;
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/314579.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

.NET中的值类型与引用类型

.NET中的值类型与引用类型这是一个常见面试题&#xff0c;值类型(Value Type)和引用类型(Reference Type)有什么区别&#xff1f;他们性能方面有什么区别&#xff1f;TL;DR&#xff08;先看结论&#xff09;值类型引用类型创建位置栈托管堆赋值时复制值复制引用动态内存分配无需…

Canada Cup 2016 C. Hidden Word 字符串构造

传送门 文章目录题意&#xff1a;思路&#xff1a;题意&#xff1a; 给你一个长度为272727的字符串sss&#xff0c;其中262626个字母每种都至少出现一次&#xff0c;让你构造一个213213213的矩阵&#xff0c;使得每个字母都出现一次&#xff0c;并且存在一条路径&#xff0c;经…

E:Johnny and Grandmaster

Johnny and Grandmaster 或许更好的阅读体验 思路 这道题就是把一组数分成两个集合&#xff0c;使这两个集合的对p的次方的和的差的最小值&#xff0c;也就是求sum1−sum2sum1 - sum2sum1−sum2得最小值&#xff0c; 由于结果过大我们可能需要对结果取模。那么这题得关键在于…

跨语言调用Hangfire定时作业服务

背景Hangfire允许您以非常简单但可靠的方式执行后台定时任务的工作。内置对任务的可视化操作。非常方便。但令人遗憾的是普遍都是业务代码和hagnfire服务本身聚合在一个程序中运行&#xff0c;极大的限制了hangfire的扩展和跨语言调用。所以萌生了开发一个支持restful api调用的…

Codeforces Round #453 (Div. 1) D. Weighting a Tree 构造 + dfs树

传送门 文章目录题意&#xff1a;思路&#xff1a;题意&#xff1a; 给你一颗nnn个点的图&#xff0c;每个点都有一个点权cic_ici​&#xff0c;要求你给每个边赋一个权值kik_iki​&#xff0c;要求对于每个点与他相连的边的权值之和等于这个点的点权cic_ici​。 n≤1e5,n−1≤…

Codeforces Round #648 (Div. 2)(A, B, C, D)

Codeforces Round #648 (Div. 2) 或许更好的阅读体验 A:Matrix Game 思路 题意可以说是非常简单的&#xff0c;我们选定的格子的行列都不能存在1&#xff0c;可以发现我们可以放的格子一定是固定的&#xff0c;然后这题就变成了技术总共可以放多少个棋子了&#xff0c;所以…

可落地微服务on k8s的持续集成/部署方案

我们隔一流的软件生产工艺还有多远&#xff1f;在距离15000公里外&#xff0c;Amazon一年可以进行5000万次部署&#xff0c;在这一边某电商平台的研发部门里&#xff0c;让他们引以为傲的是他们正在进行“敏捷”开发模式&#xff0c;并对外号称他们是以每周为迭代来进行升级。时…

Codeforces Round #579 (Div. 3) F1. Complete the Projects (easy version) 排序 + 贪心

传送门 文章目录题意&#xff1a;思路&#xff1a;题意&#xff1a; 思路&#xff1a; 比较直观的想法就是对于bi≥0b_i\ge0bi​≥0的项目&#xff0c;我们将aia_iai​从小到大排序&#xff0c;让后依次加bib_ibi​&#xff0c;如果有取不到的&#xff0c;显然就无解。否则再看…

历久弥新 - 微软万亿市值背后的文化支撑(下)|DevOps案例研究

内容来源&#xff1a;DevOps案例深度研究-Microsoft文化支撑研究战队&#xff08;本文只展示部分PPT研究成果&#xff0c;更多细节请关注案例分享会&#xff0c;及本公众号。&#xff09;本案例内容贡献者&#xff1a;陈飞&#xff08;Topic Leader&#xff09;、陈雨卿、郭子奇…

Codeforces Round #579 (Div. 3) F2. Complete the Projects (hard version) dp + 贪心

传送门 文章目录题意&#xff1a;思路&#xff1a;题意&#xff1a; 思路&#xff1a; 排序方式跟easyeasyeasy版本的一样&#xff0c;但是hardhardhard版本是输出最多能选多少&#xff0c;所以我们对b<0b<0b<0的情况不能直接贪心的来选了&#xff0c;考虑用dpdpdp来…

D:Ehab the Xorcist

或许更好的阅读体验 Ehab the Xorcist 思路 刚看时确实是一脸懵&#xff0c;最怕的就是这种构造题了&#xff0c;然后细想好像能写啊。 判断不可行的条件&#xff0c;只有两种情况&#xff1a; 一、v<uv < uv<u是一定不可能的&#xff0c;一串数的异或值一定小于…

架构杂谈《九》

微服务与轻量级通信机制微服务架构是一种架构模式&#xff0c;它提倡将单一应用程序划分成一组小的服务&#xff0c;服务之间胡亮协调、互相配合&#xff0c;为用户提供最终价值。在微服务架构中&#xff0c;服务与服务之间通信时&#xff0c;通常是通过轻量级的通信机制&#…

Codeforces Round #585 (Div. 2) E. Marbles 状压dp + 逆序对

传送门 文章目录题意&#xff1a;思路&#xff1a;题意&#xff1a; 思路&#xff1a; 考虑数列最终的状态一定是相同颜色在一起&#xff0c;所以我们发现他的颜色是有顺序的&#xff01;显然可以用状压dpdpdp来枚举颜色的顺序&#xff0c;但是又有问题了&#xff0c;你怎么确…

E:Sleeping Schedule(DP)

或许更好的阅读体验 Sleeping Schedule 思路 这道题读题就感觉像时DPDPDP&#xff0c;读完题后更加坚定了&#xff0c;这是一道DPDPDP题目。 我们考虑状态转移方程&#xff0c;dp[i][j]dp[i][j]dp[i][j]表示在第iii次入睡时间是jjj的时候的时间最优值&#xff0c;所以显然有…

GitLab CI 自动部署netcore web api 到Docker

前端篇文章中&#xff0c;我们已经成功的将asp.net core webapi在Docker容器中运行&#xff0c;并且部署了一套自己的GitLab环境。.Net & Docker&#xff08;二&#xff09;5分钟快速用Docker部署你自己的GitLab.Net & Docker&#xff08;一&#xff09;在Docker容器上…

Codeforces Round #585 (Div. 2) F. Radio Stations 2-sat + 神仙建模

传送门 文章目录题意&#xff1a;思路&#xff1a;题意&#xff1a; 你现在有ppp种电台&#xff0c;有nnn对关系(x,y)(x,y)(x,y)代表xxx电台或yyy电台中至少有一个&#xff0c;mmm对关系(x,y)(x,y)(x,y)代表xxx电台或yyy电台中最多有一个&#xff0c;每个电台有两个参数li,ril…

C. Orac and LCM(数论lcm, gcd)

C. Orac and LCM 思路 题目非常简单&#xff0c;就是求gcd(lcm(i,j))foriinrange(n),forjinrange(n),i<jgcd(lcm_(i,\ j))\ for\ i\ in\ range(n),\ for\ j\ in\ range(n),\ i\ <\ jgcd(lcm(​i, j)) for i in range(n), for j in range(n), i < j 对于包含a1a_1a1…

.net core 实现基于 cron 表达式的任务调度

.net core 实现基于 cron 表达式的任务调度Intro上次我们实现了一个简单的基于 Timer 的定时任务&#xff0c;详细信息可以看这篇文章 。但是使用过程中慢慢发现这种方式可能并不太合适&#xff0c;有些任务可能只希望在某个时间段内执行&#xff0c;只使用 timer 就显得不是那…

P6378 [PA2010] Riddle 2-sat + 前缀和优化建图

传送门 文章目录题意&#xff1a;思路&#xff1a;题意&#xff1a; 给你nnn个点mmm调变的无向图被分成kkk个部分&#xff0c;每个部分包含若干点&#xff0c;请选择一些关键点&#xff0c;使得每个部分恰好有一个关键点&#xff0c;且每条边至少有一个是关键点。 1≤k,w≤n≤…

E:Tree Queries(假树链剖分写法)

博客园地址 E&#xff1a;Tree Queries 思路 当我写完A完这道题后&#xff0c;百度了一下&#xff0c;发现好像没有人是用类树链剖分来写的&#xff0c;都是LCALCALCA&#xff0c;于是我就来水一篇树链剖分题解了。 第一步&#xff1a;贪心取点 我们可以发现&#xff0c;要…