2019/5/13 洛谷P4742 【tarjan缩点 + 拓扑dp】
题目链接:https://www.luogu.org/problemnew/show/P4742
题目大意:给一张有向图, 每个点都有点权,第一次经过该点时,该点的点权有贡献,求这张图上一条路径(终点随意)的贡献最大并且得到该路径上一个最大点权。
思路:
1.值得注意的是,这里并不是求最长路,也就是并不是求最多的点组成的路径,点可以少,但是必须点权和最大。
2.因为需要得到最大点权和以及最大点权,终点又不定,所以我们需要遍历图中每个点,来得到起点到该点的点权和以及路径上的最大点权。
3.先用tarjan进行缩点处理, 若不这样直接遍历原图非常耗时。缩点的‘点’中需要记录的信息是每个连通分量中点的权值和以及最大的点权。
4.还需要选择一个合理的遍历新图的方式, 那么选用 拓扑排序 ,(拓扑排序只有在设置汇点跳出的情况下得到的路径才不唯一,否则会根据点边关系遍历图中的每个点)
代码:
#include<stdio.h>
#include<string.h>
#include<stack>
#include<queue>
#include<algorithm>
#define mem(a, b) memset(a, b, sizeof(a))
using namespace std;
const int inf = 0x3f3f3f3f;
const int maxn = ;
const int maxm = ;
typedef long long ll; int n, m, in[maxn];
int arr[maxn], max_node[maxn], sum_color[maxn];
int cnt, new_cnt, head[maxn], new_head[maxn];
int dfn[maxn], low[maxn], vis[maxn], belong[maxn], deep, color;
int dis[maxn], d_node[maxn];//dis代表从起点到该点的点权和,d_node代表起点到该点的点权最大值
stack<int>S;
queue<int>Q; struct Edge
{
int to, next;
}edge[maxm], new_edge[maxm]; void add(int a, int b)
{
edge[++ cnt].to = b;
edge[cnt].next = head[a];
head[a] = cnt;
} void new_add(int a, int b)
{
new_edge[++ new_cnt].to = b;
new_edge[new_cnt].next = new_head[a];
new_head[a] = new_cnt;
} void tarjan(int now)
{
dfn[now] = low[now] = ++ deep;
vis[now] = ;
S.push(now);
for(int i = head[now]; i != -; i = edge[i].next)
{
int to = edge[i].to;
if(!dfn[to])
{
tarjan(to);
low[now] = min(low[now], low[to]);
}
else if(vis[to])
low[now] = min(low[now], dfn[to]);
}
if(low[now] == dfn[now])
{
color ++;
while()
{
int temp = S.top();
S.pop();
vis[temp] = ;
belong[temp] = color;
max_node[color] = max(max_node[color], arr[temp]); //存每个强连通分量里亮度最大的点的值
sum_color[color] += arr[temp];//存每个强连通分量里的亮度和
if(temp == now)
break;
}
}
} void topu_sort()
{
// mem(dis, -inf);
while(!Q.empty())
Q.pop();
for(int i = ; i <= color; i ++)//topu_sort将入度为0的入队 ,并初始化d_node,每个分量的最大亮度
{
dis[i] = sum_color[i]; //初始化dis, d_node
d_node[i] = max_node[i];
if(!in[i])
Q.push(i);
}
while(!Q.empty())
{
int temp = Q.front();
Q.pop();
for(int i = new_head[temp]; i != -; i = new_edge[i].next)
{
int to = new_edge[i].to;
in[to] --;
if(!in[to])
Q.push(to);
if(dis[to] <= dis[temp] + sum_color[to])//选择新入的点,那么d_node就要与新入的缩点比较了
{
dis[to] = dis[temp] + sum_color[to];
d_node[to] = max(d_node[temp], max_node[to]);
}
/*
else if(dis[to] == dis[temp] + sum_color[to])
d_node[to] = max(d_node[temp], max_node[to]);
*/
}
}
int sum = -;
int maxx;
for(int i = ; i <= color; i ++)
{
if(dis[i] > sum)
{
sum = dis[i];
maxx = d_node[i];
}
}
printf("%d %d\n", sum, maxx);
} int main()
{
cnt = new_cnt = deep = color = ;
mem(head, -), mem(new_head, -), mem(in, );
mem(vis, ), mem(dfn, ), mem(low, );
mem(max_node, -inf), mem(sum_color, );
scanf("%d%d", &n, &m);
for(int i = ; i <= n; i ++)
scanf("%d", &arr[i]); //存每个点的光亮值
for(int i = ; i <= m; i ++)
{
int a, b;
scanf("%d%d", &a, &b);
add(a, b);
}
for(int i = ; i <= n; i ++)
if(!dfn[i])
tarjan(i);
for(int i = ; i <= n; i ++)
{
for(int j = head[i]; j != -; j = edge[j].next)
{
int to = edge[j].to;
int x = belong[i], y = belong[to]; //将分量连边 缩点 注意是分量 belong
if(x != y)
{
new_add(x, y);
in[y] ++;
}
}
}
topu_sort();
return ;
}
2019/5/13 洛谷P4742 【tarjan缩点 + 拓扑dp】的更多相关文章
- UVA 11324.The Largest Clique tarjan缩点+拓扑dp
题目链接:https://vjudge.net/problem/UVA-11324 题意:求一个有向图中结点数最大的结点集,使得该结点集中任意两个结点u和v满足:要目u可以到达v,要么v可以到达u(相 ...
- 2019.01.04 洛谷P4719 【模板】动态dp(链分治+ddp)
传送门 ddpddpddp模板题. 题意简述:给你一棵树,支持修改一个点,维护整棵树的最大带权独立集. 思路: 我们考虑如果没有修改怎么做. 貌似就是一个sbsbsb树形dpdpdp,fi,0f_{i ...
- 洛谷P2507 [SCOI2008]配对 题解(dp+贪心)
洛谷P2507 [SCOI2008]配对 题解(dp+贪心) 标签:题解 阅读体验:https://zybuluo.com/Junlier/note/1299251 链接题目地址:洛谷P2507 [S ...
- 洛谷 P3177 [HAOI2015]树上染色 树形DP
洛谷 P3177 [HAOI2015]树上染色 树形DP 题目描述 有一棵点数为 \(n\) 的树,树边有边权.给你一个在 \(0 \sim n\)之内的正整数 \(k\) ,你要在这棵树中选择 \( ...
- 洛谷 P4072 [SDOI2016]征途 斜率优化DP
洛谷 P4072 [SDOI2016]征途 斜率优化DP 题目描述 \(Pine\) 开始了从 \(S\) 地到 \(T\) 地的征途. 从\(S\)地到\(T\)地的路可以划分成 \(n\) 段,相 ...
- NOIP2017提高组Day1T3 逛公园 洛谷P3953 Tarjan 强连通缩点 SPFA 动态规划 最短路 拓扑序
原文链接https://www.cnblogs.com/zhouzhendong/p/9258043.html 题目传送门 - 洛谷P3953 题目传送门 - Vijos P2030 题意 给定一个有 ...
- 【洛谷 P1073】 最优贸易 (Tarjan缩点+拓扑排序)
题目链接 先\(Tarjan\)缩点,记录每个环内的最大值和最小值. 然后跑拓扑排序,\(Min[u]\)表示到\(u\)的最小值,\(ans[u]\)表示到\(u\)的答案,\(Min\)和\(an ...
- 洛谷P2515 [HAOI2010]软件安装(tarjan缩点+树形dp)
传送门 我们可以把每一个$d$看做它的父亲,这样这个东西就构成了一个树形结构 问题是他有可能形成环,所以我们还需要一遍tarjan缩点 缩完点后从0向所有入度为零的点连边 然后再跑一下树形dp就行了 ...
- 洛谷 P2656 (缩点 + DAG图上DP)
### 洛谷 P2656 题目链接 ### 题目大意: 小胖和ZYR要去ESQMS森林采蘑菇. ESQMS森林间有N个小树丛,M条小径,每条小径都是单向的,连接两个小树丛,上面都有一定数量的蘑菇.小胖 ...
随机推荐
- Codevs 1629 01迷宫
1629 01迷宫 时间限制: 1 s 空间限制: 256000 KB 题目等级 : 钻石 Diamond 题目描述 Description 有一个由01组成的n*n格迷宫,若你位于一格0上,那么你可 ...
- 【luoguP3959 宝藏】-状压DP
题目描述: 参与考古挖掘的小明得到了一份藏宝图,藏宝图上标出了 n 个深埋在地下的宝藏屋, 也给出了这 n 个宝藏屋之间可供开发的m 条道路和它们的长度. 小明决心亲自前往挖掘所有宝藏屋中的宝藏.但是 ...
- luogu4281
P4281 [AHOI2008]紧急集合 / 聚会 题目描述 欢乐岛上有个非常好玩的游戏,叫做“紧急集合”.在岛上分散有N个等待点,有N-1条道路连接着它们,每一条道路都连接某两个等待点,且通过这些道 ...
- Django Admin中增加导出CSV功能
参考: https://books.agiliq.com/projects/django-admin-cookbook/en/latest/export.html 在使用Django Admin时, ...
- c 判断是否为非控制字符
#include <stdio.h> #include <wctype.h> int main () { ; wchar_t str[] = L"first line ...
- Codeforces 1205C Palindromic Paths (交互题、DP)
题目链接 http://codeforces.com/contest/1205/problem/C 题解 菜鸡永远做着变巨的梦 然而依然连div1BC题都不会做 要是那天去打cf怕是又要1题滚粗了.. ...
- 部署Hadoop2.0高性能集群
废话不多说直接实战,部署Hadoop高性能集群: 拓扑图: 一.实验前期环境准备: 1.三台主机配置hosts文件:(复制到另外两台主机上) [root@tiandong63 ~]# more /et ...
- leetcode题目142.环形链表Ⅱ(中等)
题目描述: 给定一个链表,返回链表开始入环的第一个节点. 如果链表无环,则返回 null. 为了表示给定链表中的环,我们使用整数 pos 来表示链表尾连接到链表中的位置(索引从 0 开始). 如果 p ...
- js eval 动态内容生成
js比较简单易上手,适合用于动态内容生成.或规则判断,比如给出json格式的数据,动态执行js脚本得到预期的结果等. 接口文档:包括jsConfig.jsEval两个接口 jsConfig使用get的 ...
- mysql的启动问题
用cmd启动MySQL (net start mysql )时出现(发生系统错误 5. 拒绝访问)这样的错误是因为cmd 权限太低了需要提高cmd权限才行(即使管理员权限) 如下图cmd所示: ...