题目背景

缩点+DP

题目描述

给定一个n个点m条边有向图,每个点有一个权值,求一条路径,使路径经过的点权值之和最大。你只需要求出这个权值和。

允许多次经过一条边或者一个点,但是,重复经过的点,权值只计算一次。

输入输出格式

输入格式:

第一行,n,m

第二行,n个整数,依次代表点权

第三至m+2行,每行两个整数u,v,表示u->v有一条有向边

输出格式:

共一行,最大的点权之和。

思路:

显然,由于点权为正,所以位于一个强连通分量中的结点,自然走得越多答案越大

所以,我们可以跑一边tarjan,将所有的强连通分量染色,建一个新的图

其中新图上的每个结点都代表旧图上的一个强连通分量

在跑tarjan染色的同时我们可以累加得到新图上每个点的点权

最后在新图上跑一边DP或者记忆化搜索即可

代码:

#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
#define rii register int i
#define rij register int j
using namespace std;
struct yb{
int from,to;
}y[];
struct ljb{
int to,nxt;
}x[];
int tot,dq[],sta[],sum[],head[],bnt,last[];
int n,m,dfn[],low[],top,cnt,vis[],color[],dp[];
void add(int from,int to)
{
bnt++;
x[bnt].to=to;
if(head[from]==)
{
head[from]=bnt;
}
if(last[from]!=)
{
x[last[from]].nxt=bnt;
}
last[from]=bnt;
}
void search(int wz)
{
if(dp[wz]!=)
{
return;
}
dp[wz]=sum[wz];
int maxn=;
for(rii=head[wz];i!=;i=x[i].nxt)
{
int ltt=x[i].to;
if(dp[ltt]==)
{
search(ltt);
}
maxn=max(maxn,dp[ltt]);
}
dp[wz]+=maxn;
}
void tarjan(int wz)
{
cnt++;
low[wz]=cnt;
dfn[wz]=cnt;
top++;
sta[top]=wz;
vis[wz]=;
for(rii=head[wz];i!=;i=x[i].nxt)
{
int ltt=x[i].to;
if(dfn[ltt]==)
{
tarjan(ltt);
low[wz]=min(low[wz],low[ltt]);
}
else
{
if(vis[ltt]==)
{
low[wz]=min(low[wz],dfn[ltt]);
}
}
}
if(dfn[wz]==low[wz])
{
tot++;
while(sta[top+]!=wz)
{
color[sta[top]]=tot;
sum[tot]+=dq[sta[top]];
vis[sta[top]]=;
top--;
}
}
}
int main()
{
scanf("%d%d",&n,&m);
for(rii=;i<=n;i++)
{
scanf("%d",&dq[i]);
}
for(rii=;i<=m;i++)
{
scanf("%d%d",&y[i].from,&y[i].to);
add(y[i].from,y[i].to);
}
for(rii=;i<=n;i++)
{
if(dfn[i]==)
{
tarjan(i);
}
}
/*
for(rii=1;i<=n;i++)
{
printf("%d ",color[i]);
}
cout<<endl;
*/
bnt=;
memset(head,,sizeof(head));
memset(last,,sizeof(last));
memset(x,,sizeof(x));
for(rii=;i<=m;i++)
{
if(color[y[i].from]!=color[y[i].to])
{
add(color[y[i].from],color[y[i].to]);
}
}
int ans=;
for(rii=;i<=n;i++)
{
if(dp[i]==)
{
search(i);
}
ans=max(ans,dp[i]);
}
printf("%d\n",ans);
}

【模板】缩点(tarjan,DAG上DP)的更多相关文章

  1. bzoj1093: [ZJOI2007]最大半连通子图 scc缩点+dag上dp

    一个有向图G=(V,E)称为半连通的(Semi-Connected),如果满足:?u,v∈V,满足u→v或v→u,即对于图中任意两点u,v,存在一条u到v的有向路径或者从v到u的有向路径.若G'=(V ...

  2. [正经分析] DAG上dp两种做法的区别——拓扑序与SPFA

    在下最近刷了几道DAG图上dp的题目. 要提到的第一道是NOIP原题<最优贸易>.这是一个缩点后带点权的DAG上dp,它同时规定了起点和终点. 第二道是洛谷上的NOI导刊题目<最长路 ...

  3. DAG上dp思想

    DAG上DP的思想 在下最近刷了几道DAG图上dp的题目.要提到的第一道是NOIP原题<最优贸易>.这是一个缩点后带点权的DAG上dp,它同时规定了起点和终点.第二道是洛谷上的NOI导刊题 ...

  4. BZOJ5017 [Snoi2017]炸弹[线段树优化建边+scc缩点+DAG上DP/线性递推]

    方法一: 朴素思路:果断建图,每次二分出一个区间然后要向这个区间每个点连有向边,然后一个环的话是可以互相引爆的,缩点之后就是一个DAG,求每个点出发有多少可达点. 然后注意两个问题: 上述建边显然$n ...

  5. [CF225C] Barcode (简单DAG上dp)

    题目链接:http://codeforces.com/problemset/problem/225/C 题目大意:给你一个矩阵,矩阵中只有#和.两种符号.现在我们希望能够得到一个新的矩阵,新的矩阵满足 ...

  6. bzoj1179: [Apio2009]Atm scc缩点+dag上dp

    先把强连通缩点,然后变成了dag,dp求终点是酒吧的最长路即可, /************************************************************** Pro ...

  7. EOJ Monthly 2019.2 E 中位数 (二分+中位数+dag上dp)

    题意: 一张由 n 个点,m 条边构成的有向无环图.每个点有点权 Ai.QQ 小方想知道所有起点为 1 ,终点为 n 的路径中最大的中位数是多少. 一条路径的中位数指的是:一条路径有 n 个点,将这  ...

  8. UVA 437 巴比伦塔 【DAG上DP/LIS变形】

    [链接]:https://cn.vjudge.net/problem/UVA-437 [题意]:给你n个立方体,让你以长宽为底,一个个搭起来(下面的立方体的长和宽必须大于上面的长和宽)求能得到的最长高 ...

  9. uva 437 巴比伦塔(DAG上dp)

    巴比伦塔 紫书P269 看完紫书,终于可以自己写一个dp了 :) [题目链接]巴比伦塔 [题目类型]DAG上dp &题意: 有n种立方体 n<=30,每种有无穷个,要求选一些立方体摞成一 ...

随机推荐

  1. bootstrap-datepicker汉化

    bootstrap-datepicker 是一个非常优秀的时间选择插件,默认是英文显示日期的,通过下面几个小修改让其支持默认中文 1.首先将 bootstrap-datepicker.js 另存为 u ...

  2. Linux基础之-正则表达式(grep,sed,awk)

    一. 正则表达式 正则表达式,又称规则表达式.(英语:Regular Expression,在代码中常简写为regex.regexp或RE),计算机科学的一个概念.正则表达式是对字符串操作的一种逻辑公 ...

  3. html dl dt dd 标签语法与使用

    一.dl dt dd认识 html <dl> <dt> <dd>是一组合标 […]

  4. k 近邻算法(k-Nearest Neighbor,简称kNN)

    预约助教问题: 1.计算1-NN,k-nn和linear regression这三个算法训练和查询的时间复杂度和空间复杂度? 一. WHy 最简单最初级的分类器是将全部的训练数据所对应的类别都记录下来 ...

  5. redis 在linux安装

    转自:http://futeng.iteye.com/blog/2071867 下载 官网下载 安装 tar zxvf redis-2.8.9.tar.gz cd redis-2.8.9 #直接mak ...

  6. Java—进程与线程

    进程与线程 进程是程序(任务)的执行过程,具有动态性:持有资源(共享内存.共享文件)和线程,是资源和线程的载体. 线程是系统中最小的执行单元,同一进程中有多个线程,线程共享进程的资源. 线程的交互,交 ...

  7. CefSharp开发

    CefSharp是用chromium内核开发的.net版本浏览器工具.目前只支持X86模式.所以在调试的时候要把平台改为X86 CefSharp开发指引:https://ourcodeworld.co ...

  8. [问题记录]libpomelo编译报错:ssize_t重定义

    1. 时间:2015/01/16 描述:添加libpomelo到cocos2dx项目,报错如下图所示: 解决: 修改代码,源代码: #if !defined(_SSIZE_T_) && ...

  9. Python学习---内置函数的学习

    内置函数 [Py3.5官方文档]https://docs.python.org/3.5/library/functions.html#abs Built-in Functions abs() dict ...

  10. Linux中nmon的安装与使用

    一.下载nmon. 根据CPU的类型选择下载相应的版本:http://nmon.sourceforge.net/pmwiki.php?n=Site.Downloadwget http://source ...