描述:

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

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

思路:

  tarjan 的模板之一——缩点。先利用 tarjan 出图中的强连通分量及大小(点的权值),然后遍历所有点,重新构图(←重点),根据 topo DP一下,就可得出图中最大的权值和。

标程:

#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cmath>
#include<cstring>
#include<string>
#include<cstdlib>
#include<stack>
#include<vector>
#include<queue>
#include<deque>
#include<map>
#include<set>
using namespace std;
#define maxn 1000005
int n,m,cnt1,num,top,cnt2;//cnt1 作原图的前向星,cnt2 作新图的
int ins[maxn],head[maxn],nu[maxn],dfn[maxn],low[maxn];//nu 用来去除重边(重构图用),ins 记录强连通分量的大小
int st[maxn],co[maxn];//栈只为了表示此时是否有父子关系,co判断该点是否在栈中
int h[maxn],in[maxn],dis[maxn];//h相当于新图前向星的head,in统计点的入度,dis记录权值和(in,dis都做topo排序用)
int ans=;//统计答案
struct hh
{
int to,next,from;//from,to有可以分别记录边的起点和终点
}t1[maxn],t2[maxn];//t1原图,t2新图
inline int read()
{
int kr=,xs=;
char ls;
ls=getchar();
while(!isdigit(ls))
{
if(!(ls^))
kr=-;
ls=getchar();
}
while(isdigit(ls))
{
xs=(xs<<)+(xs<<)+(ls^);
ls=getchar();
}
return xs*kr;
}
inline void add(int x,int y)
{
t1[++cnt1].next=head[x];
t1[cnt1].from=x;
t1[cnt1].to=y;
head[x]=cnt1;
}//存原图
inline void tarjan(int x)
{
low[x]=dfn[x]=++num;
st[++top]=x;co[x]=;
for (int i=head[x];i;i=t1[i].next)
{
int v=t1[i].to;
if(!dfn[v])
{
tarjan(v);
low[x]=min(low[x],low[v]);
}
else if(co[v])
{
low[x]=min(low[x],low[v]);
}
}
if (dfn[x]==low[x])
{
int y;
while(y=st[top])
{
nu[y]=x;//表示:可以从x直接到达y(单向)
co[y]=;//y出栈(记录清除)
if(x==y) break;
ins[x]+=ins[y];//合并两个强连通分量
--top;
}
--top;
}
}//日常操作
inline void topo()
{
queue <int> q;
int tot=;
for (int i=;i<=n;i++)
if (nu[i]==i&&!in[i])//该点自己到达自己,且入度为0,表示为一个被缩为一点的强连通分量(且为起始点)
{
q.push(i);
dis[i]=ins[i];
}
while (!q.empty())//依次取出所有的起点(入度为0的点)
{
int k=q.front();q.pop();
for (int i=h[k];i;i=t2[i].next)//遍历可以到达的点
{
int v=t2[i].to;
dis[v]=max(dis[v],dis[k]+ins[v]);//更新答案
in[v]--;//入度--
if(in[v]==) q.push(v);//减到这个点入度为0,扔进队列,下次再取出作为起点
}
}
for (int i=;i<=n;i++)
ans=max(ans,dis[i]);//更新最终答案
}
int main()
{
n=read();m=read();
for (int i=;i<=n;i++)
ins[i]=read();//初始每个点认为是一个强连通分量(假装是)
for (int i=;i<=m;i++)
{
int u,v;
u=read();v=read();
add(u,v);
}
for (int i=;i<=n;i++)
if(!dfn[i])
tarjan(i);
for (int i=;i<=m;i++)
{
int x=nu[t1[i].from],y=nu[t1[i].to];
if (x!=y)//←可以去除重边
{
t2[++cnt2].next=h[x];
t2[cnt2].to=y;
t2[cnt2].from=x;
h[x]=cnt2;//重构新图
in[y]++;
}
}
topo();//topo 排序
printf("%d",ans);//输出
return ;
}

tarjan 缩点(模板)的更多相关文章

  1. LuoGu-P2863牛的舞会The Cow Prom[tarjan 缩点模板]

    传送门:https://www.luogu.org/problemnew/show/P2863 思路:tarjan模板题,之前会的tarjan,一直想学缩点到底是什么操作,发现就是把同组的放在一个数组 ...

  2. 【洛谷P5008 逛庭院】tarjan缩点+贪心

    既然没有题解,那么我就来提供给一份. -- 首先我们看到数据范围.妈耶!数据这么大,一开始还想用个DP来做,但是看着就不行,那么根据这个数据范围,我们大致可以猜到这道题的算法是一个贪心,那么我们怎么贪 ...

  3. [模板]tarjan缩点+拓扑排序

    题目:给定一个n个点m条边有向图,每个点有一个权值,求一条路径,使路径经过的点权值之和最大.你只需要求出这个权值和. 允许多次经过一条边或者一个点,但是,重复经过的点,权值只计算一次. 题目简述:先t ...

  4. 洛谷 P2194 HXY烧情侣【Tarjan缩点】 分析+题解代码

    洛谷 P2194 HXY烧情侣[Tarjan缩点] 分析+题解代码 题目描述: 众所周知,HXY已经加入了FFF团.现在她要开始喜(sang)闻(xin)乐(bing)见(kuang)地烧情侣了.这里 ...

  5. BZOJ2199[Usaco2011 Jan]奶牛议会——2-SAT+tarjan缩点

    题目描述 由于对Farmer John的领导感到极其不悦,奶牛们退出了农场,组建了奶牛议会.议会以“每头牛 都可以获得自己想要的”为原则,建立了下面的投票系统: M只到场的奶牛 (1 <= M ...

  6. Tarjan&&缩点简析

    由于昨天写计蒜客初赛的一道题,看出了是缩点,但一时忘记了另外一个叫什么s...的算法怎么写了,话说我为什么没有回去翻一下自己的blog然后今天就去学了更实用也更强力的Tarjan Tarjan的思想其 ...

  7. POJ 1236 Network of Schools Tarjan缩点

    Network of Schools Time Limit: 1000MS   Memory Limit: 10000K Total Submissions: 22729   Accepted: 89 ...

  8. HDU1269(有向图缩点模板题)

    迷宫城堡 Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)Total Submis ...

  9. 初涉tarjan缩点

    tarjan缩点:口胡过好多题,不过从来没写过…… 什么是缩点 tarjan和Kosaraju.Gabow算法一样,是为了求有向图中的强连通分量.因为有向图中大多数情况下会有环存在,而有环是一个不甚好 ...

  10. POJ-3352 Road Construction,tarjan缩点求边双连通!

    Road Construction 本来不想做这个题,下午总结的时候发现自己花了一周的时间学连通图却连什么是边双连通不清楚,于是百度了一下相关内容,原来就是一个点到另一个至少有两条不同的路. 题意:给 ...

随机推荐

  1. python+selenium win32gui实现文件上传 enumerate()

    upload = dr.find_element_by_id('exampleInputFile0') upload.click() time.sleep(1) # win32gui dialog = ...

  2. django项目----函数和方法的区别

    一.函数和方法的区别 1.函数要手动传self,方法不用传 2.如果是一个函数,用类名去调用,如果是一个方法,用对象去调用 举例说明: class Foo(object): def __init__( ...

  3. 第一节 JavaScript概述

    第一节 JavaScript概述 JavaScript:其实就是对HTML+CSS静态页面进行样式修改,使其实现各种动态效果. 编写JS脚本基本步骤: 1. HTML+CSS静态布局: 2. 确定要修 ...

  4. opencv3.1线性可分svm例子及函数分析

    https://www.cnblogs.com/qinguoyi/p/7272218.html //摘自:http://docs.opencv.org/2.4/doc/tutorials/ml/int ...

  5. es6转es5在线工具

    es6转es5在线工具:https://babeljs.io/repl/# 程序员常用在线工具:https://tool.lu/

  6. 合并ts到mp4

    这个比较好用. copy /b d:\xxx\download_ts\*   d:\xxx\download_ts\new.mp4 用python ffmpeg也可以,不过我合出来有卡顿或者掉声问题, ...

  7. 【题解】Luogu P2257 YY的GCD

    原题传送门 这题需要运用莫比乌斯反演(懵逼钨丝繁衍) 显然题目的答案就是\[ Ans=\sum_{i=1}^N\sum_{j=1}^M[gcd(i,j)=prime]\] 我们先设设F(n)表示满足\ ...

  8. python元组与购物车程序

    #Author:zww ''' 程序:购物车程序 需求: 1.启动程序后,让用户输入工资,然后打印呢商品列表 2.允许用户根据商品编号购买商品 3.用户选择商品后,检测余额是否足够,够就直接扣款,不够 ...

  9. java利用poi解析excel文件

    首先需要引入以下jar包 如果使用maven,需要添加两个依赖 <dependencies> <dependency> <groupId>org.apache.po ...

  10. 关于python hashlib模块的使用

    hashlib hashlib主要提供字符加密功能,将md5和sha模块整合到了一起,支持md5,sha1, sha224, sha256, sha384, sha512等算法 #!/usr/bin/ ...