呵呵呵呵,这个sb题做了好久,然并卵,还是不对。

挖坑++

然而我感觉我做的对了,偷瞄了一下题解应该没什么问题。

这个题有n个点,n条边,所以是个基环树(我也不知道是不是这个名)

要每个点有联通,就是一个n个点的环,要是答案最小,那么我们就要保留下一些最大的链

现在我们考虑,因为一个点只有一个入度(n-1条边的话是一个严格从根节点单向向外的树),现在多了一个边,所以多了形成一个环

那先现在这个东西(基环树)就是一个环外面挂着一些严格向外延展的子树。

所以先考虑子树,对于每一个节点,贪心的保留一个权值最大的边连的儿子保留,其他的切掉(这里说的切掉是指重建),(这一步做完之后出来的东西就类似于树链剖分出来的重链)

再来考虑环,与环相连的子树,选择切掉,那么环是不用动的,选择不切,那么在环上对应的下条边是要切掉的。(这里打一个标记,判断切没切,然后,没切的话要找环上最小的边切开)

需要注意的是,可以不止一个基环树233333

 #include<bits/stdc++.h>
#define N 100005
#define LL long long
#define inf 1LL<<60
using namespace std;
inline LL ra()
{
LL x=,f=; char ch=getchar();
while (ch<'' || ch>'') {if (ch=='-') f=-; ch=getchar();}
while (ch>='' && ch<='') {x=x*+ch-''; ch=getchar();}
return x*f;
}
struct edge{
int to,next; LL v;
}e[N];
int head[N],cnt,n,start,d[N];
int top,ind,q[N],low[N],dfn[N],size[N],num,belong[N];
LL ans,sum,f[N],del,cst[N];
bool vis[N],cut,inq[N],can[N];
void insert(int x, int y, LL v)
{
e[++cnt].next=head[x]; e[cnt].to=y; e[cnt].v=v; head[x]=cnt;
}
void tarjan(int x)
{
dfn[x]=low[x]=++ind;
q[++top]=x; inq[x]=;
for (int i=head[x];i;i=e[i].next)
if (!dfn[e[i].to])
{
tarjan(e[i].to);
low[x]=min(low[e[i].to],low[x]);
}
else if (inq[e[i].to]) low[x]=min(low[x],dfn[e[i].to]);
if (low[x]==dfn[x])
{
++num;
int now=-;
while (now!=x)
{
now=q[top--];
belong[now]=num;
size[num]++;
inq[now]=;
}
}
}
void get_cost(int x)
{
can[x]=;
for (int i=head[x];i;i=e[i].next)
{
if (vis[e[i].to]) cst[x]=e[i].v;
if (e[i].to==start || !vis[e[i].to]) continue;
get_cost(e[i].to);
}
}
void solve_son(int x)
{
LL son_sum=,son_mx=;
for (int i=head[x];i;i=e[i].next)
{
son_sum+=e[i].v,son_mx=max(son_mx,e[i].v);
f[x]+=f[e[i].to];
solve_son(e[i].to);
}
f[x]+=son_sum-son_mx;
}
void dfs(int x)
{
LL son_del=-inf; can[x]=;
for (int i=head[x];i;i=e[i].next)
{
son_del=max(son_del,-cst[x]);
if (e[i].to==start) continue;
if (vis[e[i].to]) dfs(e[i].to);
else
{
solve_son(e[i].to);
ans+=f[e[i].to]+e[i].v;
son_del=max(son_del,e[i].v-cst[x]);
}
}
if (son_del>) cut=,ans-=son_del; else del=max(del,son_del);
}
int main()
{
n=ra();
for (int i=; i<=n; i++)
{
int x=ra();
LL v=(LL)ra();
if (x==i) ans+=v; else insert(x,i,v);
}
for (int i=; i<=n; i++)
if (!dfn[i]) tarjan(i);
int hehe=;
bool flag=;
for (int i=; i<=n; i++)
if (size[belong[i]]>)
{
if (hehe && hehe!=belong[i]) flag=;
hehe=belong[i];
vis[i]=;
}
for (int i=; i<=n; i++)
if (!vis[i]) {flag=; break;}
if (!flag)
{
cout<<""<<endl;
return ;
}
for (int i=; i<=n; i++)
if (vis[i] && !can[i])
{
start=i;
get_cost(i);
}
memset(can,,sizeof(can));
for (int i=; i<=n; i++)
if (vis[i] && !can[i])
{
cut=; del=-inf;
start=i; dfs(i);
if (!cut) ans-=del;
}
// for (int i=1; i<=n; i++) printf("%d ",f[i]);
cout<<ans<<endl;
return ;
}

洛谷 三月月赛 C的更多相关文章

  1. 洛谷 三月月赛 B

    搞出每一位与前一位的差,然后区间修改只是会影响区间的端点,所以只修改一下端点的值就好. %%%高一神犇线段树 #include<bits/stdc++.h> #define N 10000 ...

  2. 洛谷 三月月赛 A

    模拟模拟 #include<bits/stdc++.h> using namespace std; inline int ra() { ,f=; char ch=getchar(); ; ...

  3. 洛谷五月月赛【LGR-047】划水记

    虽然月赛有些爆炸,但我永远资瓷洛谷! 因为去接水,所以迟到了十几分钟,然后洛谷首页就打不开了-- 通过洛谷题库间接打开了比赛,看了看\(TA\),WTF?博弈论?再仔细读了读题,嗯,判断奇偶性,不过要 ...

  4. 洛谷八月月赛Round1凄惨记

    个人背景: 上午9:30放学,然后因为学校举办读书工程跟同学去书城选书,中午回来开始打比赛,下午又回老家,中间抽出一点时间调代码,回家已经8:50了 也许是7月月赛时“连蒙带骗”AK的太幸运然而因同学 ...

  5. 洛谷⑨月月赛Round2 P3393逃离僵尸岛[最短路]

    题目描述 小a住的国家被僵尸侵略了!小a打算逃离到该国唯一的国际空港逃出这个国家. 该国有N个城市,城市之间有道路相连.一共有M条双向道路.保证没有自环和重边. K个城市已经被僵尸控制了,如果贸然闯入 ...

  6. 洛谷⑨月月赛Round2 P3392涂国旗[DP]

    题目描述 某国法律规定,只要一个由N*M个小方块组成的旗帜符合如下规则,就是合法的国旗.(毛熊:阿嚏——) 从最上方若干行(>=1)的格子全部是白色的. 接下来若干行(>=1)的格子全部是 ...

  7. 5239-回忆京都-洛谷3月赛gg祭

    传送门 题目背景 第十五届东方人气投票 音乐部门 106名 第四次国内不知道东方的人对东方原曲的投票调查 51名 回忆京都副歌我tm吹爆,东方文花帖我tm吹爆! 题目描述 射命丸文在取材中发现了一个好 ...

  8. 5238-整数校验器-洛谷3月赛gg祭

    传送门 题目描述 有些时候需要解决这样一类问题:判断一个数 x是否合法. x合法当且仅当其满足如下条件: x格式合法,一个格式合法的整数要么是 0,要么由一个可加可不加的负号,一个 1到 9 之间的数 ...

  9. 洛谷九月月赛II

    题解:模拟 一旦不匹配就要break #include<iostream> #include<cstdio> #include<cstring> #include& ...

随机推荐

  1. CSP-S 2019 初赛游记

    Day 0 上午考了一套毒瘤的数据结构题,考的我心态爆炸SB出题人 晚上考了一套初赛模拟,只考1h,然后我91分,感觉初赛完全没问题? 回寝室后一直在忙活,整理东西什么的,居然将近12点睡? Day ...

  2. ubutun18 install ibus-pinyin

    ref: https://www.cnblogs.com/asmer-stone/p/9069866.html Step1 $ sudo apt-get install ibus-pinyin

  3. js中每隔一段时间执行一次

    window.setInterval("flushs()",1000); 

  4. win10安装Oracle11g

    第一步,下载 oracle 下载地址,官网(需要登录注册): http://download.oracle.com/otn/nt/oracle11g/112010/win64_11gR2_databa ...

  5. JAVA高级编程(数据源datasource)

    数据源:通过jdbc连接数据库,多建立几条连接放在数据源里面.可以设置数据源的最大连接数,同时活跃的连接数,最少空闲的连接数,能够同时接收处理的连接数等等. dbcp数据源 需要的jar包: comm ...

  6. redis之五大数据类型介绍

    目录 redis五大数据类型 1. string(字符串) 特点: 格式: 基本操作: 2. hash(哈希) 特点: 格式: 基本操作 3. list(列表) 特点 格式 基本操作 4. set(集 ...

  7. Linux下,Tomcat启动成功,发现ip:8080访问失败

    Linux下,Tomcat启动成功,发现ip:8080访问失败 Chasel_H 2018.04.23 20:47* 字数 195 阅读 566评论 0喜欢 3 相信很多人都和我一样,在Linux环境 ...

  8. java并发初探ReentrantWriteReadLock

    java并发初探ReentrantWriteReadLock ReenWriteReadLock类的优秀博客 ReentrantReadWriteLock读写锁详解 Java多线程系列--" ...

  9. ubuntu最基本的软件

    输入法: https://www.cnbawwwlogs.com/zlslch/p/6943318.html qq: http://www.linuxidc.com/Linux/2016-09/134 ...

  10. 第一章、ssh安装及远程登入配置

    1.Ubuntu下 确认 SSH Server 是否启动 输入: sudo ps -e | grep ssh. 如果正确启动, 命令行中会显示sshd. 安装服务端 OpenSSH Server 输入 ...