传送门

有向图。。

代码中有两种方法,拓扑排序和记忆化搜索

#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <queue>
#define re register
using namespace std ;
const int maxn = 1e5 + 4 ; inline int read () {
int f = 1 , x = 0 ;
char ch = getchar () ;
while(ch > '9' || ch < '0') {if(ch == '-') f = -1 ; ch = getchar () ;}
while(ch >= '0' && ch <= '9') {x = (x << 1) +(x << 3) + ch - '0' ; ch = getchar () ;}
return x * f;
} int n , m , a[maxn] , u , v , ans ;
int head[maxn] , tot , head2[maxn] , tot2 ; struct Edge {
int from , to , next ;
}edge[maxn << 1] , edge2[maxn] ; inline void add(int u , int v) {
edge[++tot].from = u ;
edge[tot].to = v ;
edge[tot].next =head[u] ;
head[u] = tot ;
} inline void add2(int u , int v) {
edge2[++tot2].from = u ;
edge2[tot2].to = v;
edge2[tot2].next = head2[u];
head2[u] = tot2;
} int stack[maxn] , belong[maxn] , top , cnt , num[maxn] ;
int low[maxn] , dfn[maxn] , ind , dis[maxn] ;
bool ins[maxn] ; inline void tarjan(int x) {
dfn[x] = low[x] = ++ind;
stack[++top] = x ;
ins[x] = true ;
for(re int i = head[x] ; i; i = edge[i].next) {
int v = edge[i].to ;
if(!dfn[v]) {
tarjan(v) ;
low[x] = min(low[x] , low[v]);
}
if(ins[v]) {
low[x] = min(low[x] , dfn[v]);
}
}
int k = 0;
if(dfn[x] == low[x]) {
++cnt;
do{
k = stack[top];
top--;
ins[k] = false;
num[cnt]++;
dis[cnt] += a[k];
belong[k] = cnt;
}while (k != x);
}
} queue<int> q;
int dis2[maxn] , in[maxn] ; inline int topo() {
for(re int i = 1 ; i <= cnt ; ++ i)
if(!in[i]) {
q.push(i);
dis2[i] = dis[i];
}
while(!q.empty()) {
int cur = q.front();
q.pop() ;
for(re int i = head2[cur] ; i ; i = edge2[i].next) {
int v = edge2[i].to ;
dis2[v] = max(dis2[v] , dis2[cur] + dis[v]) ;
in[edge2[i].to]-- ;
if(!in[edge2[i].to])
q.push(edge2[i].to) ;
}
}
for(re int i = 1 ; i <= n ; ++ i)
ans = max(ans , dis2[i]) ;
return ans;
} int main () {
n = read () ; m =read() ;
for(re int i = 1 ; i <= n ; ++ i)
a[i] = read () ;
for(re int i = 1 ; i <= m ; ++ i) {
u = read () ; v = read () ;
add(u , v) ;
}
for(re int i = 1 ; i <= n ; ++ i)
if(!dfn[i]) tarjan(i) ;
for(re int i = 1 ; i <= tot ; ++ i) {
if(belong[edge[i].from] != belong[edge[i].to]) {
add2(belong[edge[i].from] , belong[edge[i].to]) ;
in[belong[edge[i].to]]++ ;
}
}
printf("%d\n" , topo()) ;
return 0 ;
}

最新文章

  1. 怎么计算一个具体InnoDB的索引大小
  2. 代理 XP”组件已作为此服务器安全配置的一部分被关闭。系统管理员可以使用 sp_configure 来启用“代理 XP”。
  3. 2.Abstract Factory 抽象工厂(创建型模式)之简单工厂
  4. 共享内存 share pool (1):heap /extent /chunk/
  5. MRI中T1和T2的含义与区分[转]
  6. 单调栈 二 nyOj 最大矩形和
  7. 理想非常丰满,现实非常骨感——致WiFi通话
  8. 设计模式的征途—7.适配器(Adapter)模式
  9. 读书笔记-JavaScript面向对象编程(三)
  10. [转]Thunderbird 使用 Exchange 邮箱
  11. [Swift]LeetCode780. 到达终点 | Reaching Points
  12. 2018年2月19日我的java学习(——)
  13. swift计算 switch case
  14. jquery----data使用
  15. .NET 互联网技术简介
  16. Python学习笔记020——数据库中的数据类型
  17. HtmlAnchor点击之后保持高亮
  18. jdbc的简单实现demo
  19. [Eclipse]保存java文件时,自动删除不需要的包import
  20. 个人博客网站 www.superzhang.site

热门文章

  1. FastDFS分布式存储
  2. WEB入门.八 背景特效
  3. Java之初学异常
  4. Java List /ArrayList 三种遍历方法
  5. bzoj3672【NOI2014】购票
  6. linux命令总结dd命令详解
  7. [LeetCode] 208. Implement Trie (Prefix Tree) ☆☆☆
  8. 值得关注的sql-on-hadoop框架
  9. 【AtCoder Grand Contest 012C】Tautonym Puzzle [构造]
  10. Bzoj4763 雪辉