题目链接:http://codeforces.com/problemset/problem/894/E

题目大意:

$n$个点$m$条边的有向图,每条边有一个权值,可以重复走。

第$i$次走过某条边权为$w$的边后这条边的边权变成$w-i$,但不能小于等于$0$。

给定起点,询问任意走最多能获得多少的边权

题解:

显然一个强联通分量的边可以全部走到$0$为止。

考虑强连通分量中一条边权为w的边对答案的贡献,$s=w+w-1+w-1-2+w-1-2-3\ldots$

设这个式子有$t+1$项,显然有$\frac{(t+1)t}{2}<=w$,解得$t=\sqrt{2w+0.25}-0.5$,t下取整

那么$s=(t+1)w-\frac{(t+2)(t+1)t}{6}$

得到每个强连通分量之后剩下的部分拓扑排序后DP即可

#include<algorithm>
#include<cstring>
#include<cstdio>
#include<iostream>
#include<vector>
#include<queue>
#include<cmath>
typedef long long ll;
using namespace std; const int N=1e6+;
const int MAX=1e8+;
const ll inf=1ll<<;//这个要足够大,卡了2h...
int n,m,tot,top,tim,scc,t;
int sta[N],dfn[N],low[N],belong[N],deg[N],head[N];
bool ins[N];
ll dp[N],val[N],sum[N],tmp[N];
struct EDGE
{
int from,to,nxt;ll w;
}edge[N];
struct node{int v;ll w;};
vector <node> g[N];
inline ll read()
{
char ch=getchar();
ll s=,f=;
while (ch<''||ch>'') {if (ch=='-') f=-;ch=getchar();};
while (ch>=''&&ch<='') {s=(s<<)+(s<<)+ch-'';ch=getchar();}
return s*f;
}
void add(int u,int v,int w)
{
edge[++tot]=(EDGE){u,v,head[u],w};
head[u]=tot;
}
void tarjan(int x)
{
dfn[x]=low[x]=++tim;
ins[x]=;sta[++top]=x;
for (int i=head[x];i;i=edge[i].nxt)
{
int y=edge[i].to;
if (!dfn[y])
{
tarjan(y);
low[x]=min(low[x],low[y]);
}
else if (ins[y]) low[x]=min(low[x],dfn[y]);
}
if (dfn[x]==low[x])
{
++scc;int k;
do
{
k=sta[top--];
belong[k]=scc;
ins[k]=;
}
while(k!=x);
}
}
inline ll calc(ll x)
{
ll tt=sqrt(*x+0.25)-0.5;
return x+tt*x-(tt+)*(tt+)*tt/;
}
int main()
{
//for (t=1;tmp[t-1]<MAX;t++) {tmp[t]=tmp[t-1]+t;sum[t]=sum[t-1]+tmp[t];}
n=read();m=read();
for (int i=,u,v,w;i<=m;i++)
{
u=read();v=read();w=read();
add(u,v,w);
}
for (int i=;i<=n;i++) if (!dfn[i]) tarjan(i);
for (int i=;i<=m;i++)
{
int u=edge[i].from,v=edge[i].to;
u=belong[u],v=belong[v];
if (u==v) val[u]+=calc(edge[i].w);
}
for (int u=;u<=n;u++)
{
for (int i=head[u];i;i=edge[i].nxt)
{
int v=edge[i].to;
int bu=belong[u],bv=belong[v];
if (bu==bv) continue;
g[bu].push_back((node){bv,edge[i].w+val[bv]});
deg[bv]++;
}
}
int st=read();st=belong[st];
queue <int> q;
for (int i=;i<=scc;i++) dp[i]=-inf;dp[st]=val[st];
for (int i=;i<=scc;i++) if (!deg[i]) q.push(i);
while (!q.empty()){
int k=q.front();q.pop();
for (int i=;i<g[k].size();i++){
int y=g[k][i].v;
if (--deg[y]==) q.push(y);
dp[y]=max(dp[y],dp[k]+g[k][i].w);
}
}
ll mx=;
for (int i=;i<=scc;i++) mx=max(mx,dp[i]);
printf("%lld\n",mx);
return ;
}

[codeforces 894 E] Ralph and Mushrooms 解题报告 (SCC+拓扑排序+DP)的更多相关文章

  1. 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 ...

  2. [JZOJ 5905] [NOIP2018模拟10.15] 黑暗之魂(darksoul) 解题报告 (拓扑排序+单调队列+无向图基环树)

    题目链接: http://172.16.0.132/senior/#main/show/5905 题目: oi_juruo热爱一款名叫黑暗之魂的游戏.在这个游戏中玩家要操纵一名有 点生命值的无火的余灰 ...

  3. Codeforces Round #292 (Div. 1) B. Drazil and Tiles 拓扑排序

    B. Drazil and Tiles 题目连接: http://codeforces.com/contest/516/problem/B Description Drazil created a f ...

  4. CodeForces 721C Journey(拓扑排序+DP)

    <题目链接> 题目大意:一个DAG图有n个点,m条边,走过每条边都会花费一定的时间,问你在不超过T时间的条件下,从1到n点最多能够经过几个节点. 解题分析:对这个有向图,我们进行拓扑排序, ...

  5. Codeforces Round #541 (Div. 2) D 并查集 + 拓扑排序

    https://codeforces.com/contest/1131/problem/D 题意 给你一个n*m二维偏序表,代表x[i]和y[j]的大小关系,根据表构造大小分别为n,m的x[],y[] ...

  6. codeforces C1. The Great Julya Calendar 解题报告

    题目链接:http://codeforces.com/problemset/problem/331/C1 这是第一次参加codeforces比赛(ABBYY Cup 3.0 - Finals (onl ...

  7. codeforces B. Eugeny and Play List 解题报告

    题目链接:http://codeforces.com/problemset/problem/302/B 题目意思:给出两个整数n和m,接下来n行给出n首歌分别的奏唱时间和听的次数,紧跟着给出m个时刻, ...

  8. codeforces 433C. Ryouko's Memory Note 解题报告

    题目链接:http://codeforces.com/problemset/problem/433/C 题目意思:一本书有 n 页,每页的编号依次从 1 到 n 编排.如果从页 x 翻到页 y,那么| ...

  9. codeforces 556B. Case of Fake Numbers 解题报告

    题目链接:http://codeforces.com/problemset/problem/556/B 题目意思:给出 n 个齿轮,每个齿轮有 n 个 teeth,逆时针排列,编号为0 ~ n-1.每 ...

随机推荐

  1. Oracle数据库中闪回恢复的详细分析

    Oracle9i开始提供闪回查询,以便能在需要的时候查到过去某个时刻的一致性数据,这是通过Undo实现的.这个功能有很大的限制,就是相关事务的undo不能被覆盖,否则就无力回天了.oracle10g大 ...

  2. ChildViewController

    View Controller中可以添加多个sub view,在需要的时候显示出来: 可以通过viewController(parent)中可以添加多个child viewController;来控制 ...

  3. SQL语句之Group By

    1. Group By 语句简介: Group By语句从英文的字面意义上理解就是“根据(by)一定的规则进行分组(Group)”.它的作用是通过一定的规则将一个数据集划分成若干个小的区域,然后针对若 ...

  4. Spark on YARN运行模式(图文详解)

    不多说,直接上干货! 请移步 Spark on YARN简介与运行wordcount(master.slave1和slave2)(博主推荐) Spark on YARN模式的安装(spark-1.6. ...

  5. [转]java多线程并发去调用一个类的静态方法安全性探讨

    文章转自:https://blog.csdn.net/weibin_6388/article/details/50750035 这篇文章主要讲多线程对静态方法访问的数据安全性 总结如下: 1,java ...

  6. canvas绘制饼型图

    <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...

  7. Java操作Kafka执行不成功

    使用kafka-clients操作kafka始终不成功,原因不清楚,下面贴出相关代码及配置,请懂得指点一下,谢谢! 环境及依赖 <dependency> <groupId>or ...

  8. VS运行程序发生栈溢出的分析

    这两天时间都浪费在解决各种栈溢出了,没想到最后各个部件合在一起的时候会出现这么多的问题,这其实是我第一次解决栈溢出问题,很认真的查了查资料,找了几种解决方法,但是作用都不大,拆了东墙补西墙,虽然知道及 ...

  9. ZBrush2018中文版全球同步发售,终身授权

    ZBrush 2018于2018.3.28发布了!这个我们期待已久的2018新版本等了几年,它终于来了! 不负众望,ZBrush 2018的这一次更新,简直炸裂,新功能真是太好用了!2018版是ZBr ...

  10. ZBrush软件特性之Color调控板

    ZBrush®中的Color调色板显示当前颜色并提供数值的方法选择颜色,而且选择辅助色,使用描绘工具可以产生混合的色彩效果. ZBrush 4R8下载:http://wm.makeding.com/i ...