传送门

这是一道英语题,首先要读懂题目:

$\text{Alex believes that his trip will be interesting only if he will not use any road twice in a row.}$

这句话意思是不会连续走一条路,但是同一条路是可以走多次的

所以对于一个边双联通分量,是可以全部走一遍并可以从联通分量里的任意一个点离开的

所以就可以直接缩点,然后就变成树上问题

发现对于树上的点,如果它的大小为 $1$ 并且它的儿子都没法返回 ,那么到达它以后就没法返回,反之一定可以返回(自己内部绕一圈或者走到儿子再回来即可)

考虑树上搞搞 $dp$,设 $f[x]$ 表示走完 $x$ 的子树以后并能返回 $x$ 的父亲时得到的最大价值,$g[x]$ 表示走完 $x$ 的子树不返回的最大价值

那么对于一个可以返回父亲的的子节点 $v$ ,有转移:$f[x]+=f[v]$

对于 $g[x]$ ,比较复杂,首先 $g[x]$ 可以是 $x$ 走完所有可以返回的儿子,最后再走到一个不能返回的儿子:$g[x]=f[x]+g[v]$

也可以是走到某个虽然可以返回,但是没必要返回的儿子里面不返回(因为儿子再往下走到不能返回的节点最终价值可能更大):$g[x]=g[x]-f[v]+g[v]$,这里减去 $f[v]$ 是因为之前加上了

然后最后答案就是 $g[root]$

#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
#include<cmath>
#include<vector>
using namespace std;
typedef long long ll;
inline int read()
{
int x=,f=; char ch=getchar();
while(ch<''||ch>'') { if(ch=='-') f=-; ch=getchar(); }
while(ch>=''&&ch<='') { x=(x<<)+(x<<)+(ch^); ch=getchar(); }
return x*f;
}
const int N=4e5+;
int n,m,a[N];
int fir[N],from[N<<],to[N<<],cntt;
inline void add(int a,int b) { from[++cntt]=fir[a]; fir[a]=cntt; to[cntt]=b; }
int dfn[N],low[N],bel[N],st[N],sz[N],Top,cnt,tot;
void Tarjan(int x,int fa)
{
dfn[x]=low[x]=++cnt; st[++Top]=x;
for(int i=fir[x];i;i=from[i])
{
int &v=to[i]; if(v==fa) continue;
if(!dfn[v]) Tarjan(v,x),low[x]=min(low[x],low[v]);
else if(!bel[v]) low[x]=min(low[x],dfn[v]);
}
if(low[x]!=dfn[x]) return;
tot++; while(st[Top]!=x) bel[st[Top--]]=tot;
bel[st[Top--]]=tot;
}
struct edge {
int u,v;
edge (int _u=,int _v=) { u=_u,v=_v; }
inline bool operator < (const edge &tmp) const {
return u!=tmp.u ? u<tmp.u : v<tmp.v;
}
inline bool operator == (const edge &tmp) const {
return u==tmp.u&&v==tmp.v;
}
};
vector <edge> tmp;
vector <int> V[N];
ll val[N];
void build()
{
for(int i=;i<=n;i++) val[bel[i]]+=a[i],sz[bel[i]]++;
for(int i=;i<=n;i++)
for(int j=fir[i];j;j=from[j])
{
int &v=to[j]; if(bel[i]==bel[v]) continue;
tmp.push_back(edge(bel[i],bel[v]));
}
sort(tmp.begin(),tmp.end());
tmp.resize( unique(tmp.begin(), tmp.end()) - tmp.begin() );
for(auto E: tmp) V[E.u].push_back(E.v);
}
ll f[N],g[N];
bool ret[N];
void dfs(int x,int fa)
{
f[x]=val[x]; if(sz[x]>) ret[x]=;
ll mx=;
for(auto v:V[x])
{
if(v==fa) continue;
dfs(v,x);
if(ret[v]) f[x]+=f[v],ret[x]=;
else mx=max(mx,g[v]);
}
g[x]=f[x]+mx;
for(auto v:V[x])
if(v!=fa&&ret[v])
g[x]=max(g[x], f[x]-f[v]+g[v] );
}
int main()
{
n=read(),m=read(); int x,y;
for(int i=;i<=n;i++) a[i]=read();
for(int i=;i<=m;i++)
{
x=read(),y=read();
add(x,y); add(y,x);
}
int s=read();
for(int i=;i<=n;i++) if(!dfn[i]) Tarjan(i,);
build();
dfs(bel[s],);
printf("%lld\n",g[bel[s]]);
return ;
}

Codeforces 1220E. Tourism的更多相关文章

  1. CF-diary

    (做题方式:瞟题解然后码) 1238E. Keyboard Purchase \(\texttt{Difficulty:2200}\) 题意 给你一个长度为 \(n\) 的由前 \(m\) 个小写字母 ...

  2. Codeforces Round #586 (Div. 1 + Div. 2) E. Tourism

    链接: https://codeforces.com/contest/1220/problem/E 题意: Alex decided to go on a touristic trip over th ...

  3. Codeforces 1220 E Tourism

    题面 可以发现一个边双必然是可以随意走的,所以我们就把原图求割边然后把边双缩成一个点,然后就是一个树上dp了. #include<bits/stdc++.h> #define ll lon ...

  4. Codeforces 杂题集 2.0

      记录一些没有写在其他随笔中的 Codeforces 杂题, 以 Problemset 题号排序   1326D2 - Prefix-Suffix Palindrome (Hard version) ...

  5. Codeforces Round #635 (Div. 2) 题解

    渭城朝雨浥轻尘,客舍青青柳色新. 劝君更尽一杯酒,西出阳关无故人.--王维 A. Ichihime and Triangle 网址:https://codeforces.com/contest/133 ...

  6. python爬虫学习(5) —— 扒一下codeforces题面

    上一次我们拿学校的URP做了个小小的demo.... 其实我们还可以把每个学生的证件照爬下来做成一个证件照校花校草评比 另外也可以写一个物理实验自动选课... 但是出于多种原因,,还是绕开这些敏感话题 ...

  7. 【Codeforces 738D】Sea Battle(贪心)

    http://codeforces.com/contest/738/problem/D Galya is playing one-dimensional Sea Battle on a 1 × n g ...

  8. 【Codeforces 738C】Road to Cinema

    http://codeforces.com/contest/738/problem/C Vasya is currently at a car rental service, and he wants ...

  9. 【Codeforces 738A】Interview with Oleg

    http://codeforces.com/contest/738/problem/A Polycarp has interviewed Oleg and has written the interv ...

随机推荐

  1. LeetCode 114. 二叉树展开为链表(Flatten Binary Tree to Linked List)

    题目描述 给定一个二叉树,原地将它展开为链表. 例如,给定二叉树 1 / \ 2 5 / \ \ 3 4 6 将其展开为: 1 \ 2 \ 3 \ 4 \ 5 \ 6 解题思路 二叉树转化为链表的基本 ...

  2. python:将numpy数组写入csv文件

    import numpy as np np.savetxt('E:\\forpython\\featvector.csv',data_to_save,delimiter=',')

  3. ANTLR4将JSON翻译成XML

    实现功能:构建一个JSON到XML的翻译器. antlr4文件: grammar JSON; json : object | array ; object : '{' pair (',' pair)* ...

  4. C#类型转换类(通用类)

    //     /// 类型转换类     /// 处理数据库获取字段为空的情况     ///     public static class DBConvert     {         #reg ...

  5. Copy-On-Write in Swift

    Premature optimisation is the root of all evil. But, there are moments where we need to optimise our ...

  6. AWS EC2 外网不能访问的坑

    概述 今天我在 AWS EC2 上配置并启动了 nginx,但是通过外网不能访问,查了一下资料终于解决了,记录下来供以后开发时参考,相信对其它人也有用. 外网访问不了的原因 外网访问不了的原因不外乎有 ...

  7. LinuxE2系统刷机后OSCAM安装与读卡器设置

    我也属于E2小白,最近才开始玩这个系统.从dinobot 4k+,到H7s,在到H5,各种E2机器都买了.刚开始入手的时候,怎么这么麻烦?慢慢的发现,烧新,玩E2也是一种乐趣,只不过最近困扰我的刷机后 ...

  8. 如何优雅的给TDatetimePicker控件赋值(Delphi)

    给DatetimePicker赋值时,可以通过界面设置赋值,也可以通过代码赋值. 通常,我们会给表示起始时间的dtp赋值为 00:00:00,给表示结束时间的dtp赋值为23:59:59. 代码如下: ...

  9. 记:倍福(CP2611 Control Panel)了解

    型号:CP2611 Control Panel Multitouch 11 为啥选型?嗯!因为不了解,了解了,作为只运行.net客户端窗体程序,谁会选用他,不是说他不好,反而相反,他是很优秀的嵌入式集 ...

  10. Flume概述

    flume是分布式的,可靠的,用于从不同的来源有效收集 聚集 和 移动 大量的日志数据用以集中式的数据存储的系统. 是apache的一个顶级项目. 系统需求:jdk1.6以上,推荐java1.7