题意

给定$n$个点$m$条边有向图及边权$w$,第$i$次经过一条边边权为$w-1-2.-..-i$,$w\ge 0$给定起点$s$问从起点出发最多能够得到权和,某条边可重复经过


有向图能够重复经过的边当且仅当成环,所以tarjan缩点成DAG,缩点后每个点内的权值可以通过二分算出,假设最大的$n$使得$w-\frac{n(n+1)}{2}\ge 0$,那么该点值为$(n+1)w-\frac{n(n+1)(n+2)}{6}$,通过对DAG进行dp算出最长路就是答案

代码

#include <bits/stdc++.h>
#define inf 0x7f7f7f7f
using namespace std;
typedef long long LL;
const int N = 1000005;
int n, m, x, y, w, s;
int head[N], nxt[N], to[N], val[N], cnt;
inline void init(){memset(head, -1, sizeof(head)); cnt = 0;}
inline void add(int u, int v, int w) {to[cnt] = v, val[cnt] = w, nxt[cnt] = head[u], head[u] = cnt++;}
int head2[N], nxt2[N], to2[N], cnt2; LL val2[N];
inline void init2() {memset(head2, -1, sizeof(head)); cnt2 = 0;}
inline void add2(int u, int v, LL w) {to2[cnt2] = v, val2[cnt2] = w, nxt2[cnt2] = head2[u], head2[u] = cnt2++;}
int dfs_ind = 1, dfn[N], low[N], sccno[N], scc_cnt = 0;
LL w_[N];
stack<int> st;
void tarjan(int u) {
dfn[u] = low[u] = dfs_ind++;
st.push(u);
for(int i = head[u]; ~i; i = nxt[i]) {
int v = to[i];
if(!dfn[v]) {tarjan(v); low[u] = min(low[u], low[v]);}
else if(!sccno[v]) {low[u] = min(low[u], dfn[v]);}
}
if(dfn[u] == low[u]) {
scc_cnt++;
while(1) {
int x = st.top(); st.pop();
sccno[x] = scc_cnt;
if(x == u) break;
}
}
}
inline LL cal(LL x) {
LL n = sqrt(2.0 * x + 0.25) - 0.5;
return (n + 1) * x - (n + 1) * (n + 2) * n / 6;
}
void DAG() {
memset(dfn,0,sizeof(dfn));
memset(low,0,sizeof(low));
memset(sccno,0,sizeof(sccno));
memset(w_,0,sizeof(w_));
init2();
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 = nxt[j]) {
int v = to[j];
if(sccno[i] != sccno[v]) {
add2(sccno[i], sccno[v], 1LL * val[j]);
}else w_[sccno[i]] += cal(val[j]);
}
}
}
LL dp[N];
void dfs(int u) {
if(~dp[u]) return;
dp[u] = w_[u];
for(int i = head2[u]; ~i; i = nxt2[i]) {
dfs(to2[i]);
dp[u] = max(dp[u], w_[u] + dp[to2[i]] + val2[i]);
}
}
int main() {
init();
scanf("%d%d", &n, &m);
for(int i = 1; i <= m; ++i) {
scanf("%d%d%d", &x, &y, &w);
add(x, y, w);
}
scanf("%d", &s);
DAG();
memset(dp, -1, sizeof(dp));
dfs(sccno[s]);
cout << dp[sccno[s]] << endl;
return 0;
}

【Codeforces】894E.Ralph and Mushrooms Tarjan缩点+DP的更多相关文章

  1. CodeForces - 894E Ralph and Mushrooms (强连通缩点+dp)

    题意:一张有向图,每条边上都有wi个蘑菇,第i次经过这条边能够采到w-(i-1)*i/2个蘑菇,直到它为0.问最多能在这张图上采多少个蘑菇. 分析:在一个强连通分量内,边可以无限次地走直到该连通块内蘑 ...

  2. 硬币问题 tarjan缩点+DP 莫涛

    2013-09-15 20:04 题目描述 有这样一个游戏,桌面上摆了N枚硬币,分别标号1-N,每枚硬币有一个分数C[i]与一个后继硬币T[i].作为游戏参与者的你,可以购买一个名为mlj的小机器人, ...

  3. Codeforces 949C(Data Center Maintenance,Tarjan缩点)

    难度系数:1900 graphs 题意:有 n 个银行,m 个客户,每个客户都把自己的资料放在 2 个银行,一天总共有 h 小时,每个银行每天都要维护一小时,这一小时内银行无法工作,但是这一小时客户仍 ...

  4. BZOJ 1179 (Tarjan缩点+DP)

    题面 传送门 分析 由于一个点可以经过多次,显然每个环都会被走一遍. 考虑缩点,将每个强连通分量缩成一个点,点权为联通分量上的所有点之和 缩点后的图是一个有向无环图(DAG) 可拓扑排序,按照拓扑序进 ...

  5. Libre OJ 2255 (线段树优化建图+Tarjan缩点+DP)

    题面 传送门 分析 主体思路:若x能引爆y,从x向y连一条有向边,最后的答案就是从x出发能够到达的点的个数 首先我们发现一个炸弹可以波及到的范围一定是坐标轴上的一段连续区间 我们可以用二分查找求出炸弹 ...

  6. NOIP2009最优贸易[spfa变形|tarjan 缩点 DP]

    题目描述 C 国有 n 个大城市和 m 条道路,每条道路连接这 n 个城市中的某两个城市.任意两个 城市之间最多只有一条道路直接相连.这 m 条道路中有一部分为单向通行的道路,一部分 为双向通行的道路 ...

  7. Codeforces 894.E Ralph and Mushrooms

    E. Ralph and Mushrooms time limit per test 2.5 seconds memory limit per test 512 megabytes input sta ...

  8. Codeforces Round #447 (Div. 2)E. Ralph and Mushrooms

    Ralph is going to collect mushrooms in the Mushroom Forest. There are m directed paths connecting n  ...

  9. 【题解】CF894E Ralph and Mushrooms (缩点)

    [题解]CF894E Ralph and Mushrooms (缩点) 这是紫?给个解方程算法 考虑一条边若可以重复遍历说明一定有环,有环的话一定会把环上的蘑菇榨干,考虑一条边从全部到榨干的贡献是多少 ...

随机推荐

  1. Windows Thin PC体验 & 语言包更改(win 7 included)

    本作品由Man_华创作,采用知识共享署名-非商业性使用-相同方式共享 4.0 国际许可协议进行许可.基于http://www.cnblogs.com/manhua/上的作品创作. 简介: Window ...

  2. CSS3 background属性

    background: #00FF00 url(bgimage.gif) no-repeat fixed top; background 简写属性在一个声明中设置所有的背景属性. 可以设置如下属性: ...

  3. DevOps必备的20款顶级工具

    原文地址:http://os.51cto.com/art/201606/512423.htm 开发运维工具与软件开发领域的最佳实践密切相关,也与必要的规范密切相关.在整个开发生命周期涉及到一大批新旧工 ...

  4. .net发布网站步骤

    本文章分为三个部分: web网站发布.IIS6 安装方法.ASP.NET v4.0 安装方法 一.web网站发布 1.打开 Visual Studio 2013 编译环境 2.在其解决方案上右击弹出重 ...

  5. RF--- selenium

  6. hdu 4862 KM算法 最小K路径覆盖的模型

    http://acm.hdu.edu.cn/showproblem.php?pid=4862 选t<=k次,t条路要经过全部的点一次而且只一次. 建图是问题: 我自己最初就把n*m 个点分别放入 ...

  7. ubuntu 下开源安装

    常用开源库安装: 0.安装g++: sudo apt-get install g++ 1.首先不可或缺的就是编译器与基本的函式库: sudo apt-get install build-essenti ...

  8. Bootstrp--一个导航面板切换的实用例子

    <!--导航区开始--> <ul class="nav nav-tabs nav-stacked" role="tablist"> &l ...

  9. MySQL 5.7.18的安装及主从复制(主从同步)

    MySQL 5.7.18的安装与主从复制 IP 计算机名 角色 192.168.1.222 001 master 192.168.1.233 002 slave CentOS 6.9安装mysql5. ...

  10. [转]XMPP基本概念--节(stanza)

    本文介绍在XMPP通信中最核心的三个XML节(stanza).这些节(stanza)有自己的作用和目标,通过组织不同的节(stanza),就能达到我们各种各样的通信目的. 首先我们来看一段XMPP流. ...