------------恢复内容开始------------

题目链接

https://atcoder.jp/contests/agc033/tasks/agc033_f

题解

又被神仙题搞自闭了……
首先让我们来读错题:把题面里的"in some order"改成"in this order"! 似乎变简单了很多!
显然一条边\((u,v)\)会被产生当且仅当在原图上存在从\(u\)到\(v\)的一条路径,使得这条路径上的点依次位于树上的一条路径上。然后我们可以从每个点开始BFS或DFS确定答案。
但是现在的题意是"in some order", 没有对路径上三个点的经过顺序进行约束。那么我们考虑把它强行转化成顺序确定的情况。
假设存在\((a,b,c)\)满足在树上\(b\)在\(a,c\)的路径上且在图上\(a,b\)和\(a,c\)之间都有连边,那么把\(a,c\)的连边去掉,连上\(b,c\)的边。假设我们这样操作直到不能操作为止,那么新的图产生的边和原图是一样的,且新图加边过程中三个点在树的路径上出现的顺序一定和"in this order"保持一致,然后直接采用刚才的做法做即可。
现在考虑如何做上面所说的操作。用\(f[u][v]\)维护以\(u\)为根时如果添加一条\((u,v)\)的边,那么实际上\(u\)端点会被哪个点替代,然后每次新加一条图的边,先把这条边缩到最短,然后再分别在以\(u\)为根\(v\)子树内和以\(v\)为根\(u\)子树内找其他能缩的边以及更新\(f\),详见代码。
复杂度分析:发现我们每遍历一个点,要么会缩一条边,要么会使得\(f\)数组里\(f[u][v]=u\)的个数减少\(1\), 故总时间复杂度\(O(n^2+nm)\).

代码

#include<bits/stdc++.h>
#define llong long long
#define mkpr make_pair
#define pii pair<int,int>
#define riterator reverse_iterator
using namespace std;inline int read()
{int x = 0,f = 1; char ch = getchar();for(;!isdigit(ch);ch=getchar()) {if(ch=='-') f = -1;}for(; isdigit(ch);ch=getchar()) {x = x*10+ch-48;}return x*f;
}const int N = 2e3;
struct Edge
{int v,nxt;
} e[(N<<1)+3];
int fe[N+3];
int fa[N+3][N+3];
int f[N+3][N+3];
int n,m,en,ans;void addedge(int u,int v)
{en++; e[en].v = v;e[en].nxt = fe[u]; fe[u] = en;
}void dfs1(int rt,int u)
{for(int i=fe[u]; i; i=e[i].nxt){int v = e[i].v; if(v==fa[rt][u]) continue;fa[rt][v] = u;dfs1(rt,v);}
}void addedgeg(int u,int v)
{if(f[u][v]==v||f[v][u]==u) {return;}
//  printf("addedgeg %d %d %d %d\n",u,v,f[u][v],f[v][u]);if(f[u][v]!=u) {addedgeg(f[u][v],v); return;}if(f[v][u]!=v) {addedgeg(u,f[v][u]); return;}f[u][v] = v,f[v][u] = u;vector<pii> ext; queue<int> que;que.push(v);while(!que.empty()){int cu = que.front(); que.pop();for(int i=fe[cu]; i; i=e[i].nxt){int cv = e[i].v; if(cv==fa[u][cu]) continue;if(f[u][cv]==u) {f[u][cv] = v; que.push(cv);}else {ext.push_back(mkpr(v,cv));}}}que.push(u);while(!que.empty()){int cu = que.front(); que.pop();for(int i=fe[cu]; i; i=e[i].nxt){int cv = e[i].v; if(cv==fa[v][cu]) continue;if(f[v][cv]==v) {f[v][cv] = u; que.push(cv);}else {ext.push_back(mkpr(u,cv));}}}for(int i=0; i<ext.size(); i++){addedgeg(ext[i].first,ext[i].second);}
}void dfs2(int rt,int u,int prv)
{if(u!=rt && f[prv][u]==u) {ans++; prv = u;}for(int i=fe[u]; i; i=e[i].nxt){int v = e[i].v; if(v==fa[rt][u]) continue;dfs2(rt,v,prv);}
}int main()
{scanf("%d%d",&n,&m);for(int i=1; i<n; i++) {int u,v; scanf("%d%d",&u,&v); addedge(u,v); addedge(v,u);}for(int i=1; i<=n; i++){dfs1(i,i);}for(int i=1; i<=n; i++) for(int j=1; j<=n; j++) f[i][j] = i;for(int i=1; i<=m; i++){int x,y; scanf("%d%d",&x,&y);addedgeg(x,y);}for(int i=1; i<=n; i++){dfs2(i,i,i);}printf("%d\n",ans>>1);return 0;
}

------------恢复内容结束------------

AtCoder AGC033F Adding Edges (图论)相关推荐

  1. AtCoder AGC043C Giant Graph (图论、SG函数、FWT)

    题目链接 https://atcoder.jp/contests/agc043/tasks/agc043_c 题解 场上感觉没啥思路就放弃了,场下想了十几分钟发现是水题,血亏...(只能怪自己计数水平 ...

  2. AtCoder AGC038D Unique Path (图论)

    题目链接 https://atcoder.jp/contests/agc038/tasks/agc038_d 题解 orz zjr神仙做法 考虑把所有\(C_i=0\)的提示的两点连边,那么连完之后的 ...

  3. AtCoder AGC022C Remainder Game (图论)

    题目链接 https://atcoder.jp/contests/agc022/tasks/agc022_c 题解 大水题一道 就他给的这个代价,猜都能猜到每个数只能用一次 仔细想想,我们肯定是按顺序 ...

  4. AtCoder AGC036D Negative Cycle (图论、DP)

    题目链接 https://atcoder.jp/contests/agc036/tasks/agc036_d 题解 这都是怎么想出来的啊..目瞪口呆系列.. 第一步转化至关重要: 一张图中不存在负环意 ...

  5. 层次聚类算法 算法_聚类算法简介

    层次聚类算法 算法 Take a look at the image below. It's a collection of bugs and creepy-crawlies of different ...

  6. 【论文阅读】A Gentle Introduction to Graph Neural Networks [图神经网络入门](6)

    [论文阅读]A Gentle Introduction to Graph Neural Networks [图神经网络入门](6) GNN playground Some empirical GNN ...

  7. 【2019浙江省赛 - A】Vertices in the Pocket(权值线段树下二分,图,思维)

    题干: DreamGrid has just found an undirected simple graph with  vertices and no edges (that's to say, ...

  8. 最小生成树 kruskal_使用Kruskal算法求解Java最小生成树问题

    最小生成树 kruskal In Electronic Circuit we often required less wiring to connect pins together. We can m ...

  9. 7 款 Python 可视化工具对比

    Python 的科学栈相当成熟,各种应用场景都有相关的模块,包括机器学习和数据分析.数据可视化是发现数据和展示结果的重要一环,只不过过去以来,相对于 R 这样的工具,发展还是落后一些. 幸运的是,过去 ...

最新文章

  1. RichEdit使用大全
  2. ios开发值json数据文件的存取
  3. PX4飞控之导航及任务架构
  4. 修改mysql表的存储引擎
  5. POJ3764 The xor-longest Path(Trie树)
  6. C语言字符串分离数字和字母,请问这个用c怎么做:输入一串字符,分别统计其中数字和字母的个数...
  7. pptx给幻灯片添加内容
  8. [转] js前端解决跨域问题的8种方案(最新最全)
  9. Xshell连接Linux下Oracle无法回退的解决办法
  10. 漫画算法python版下载_漫画算法-小灰的算法之旅.pdf
  11. OpenCV滤波器 龙门石窟篇【Python-Open_CV系列(九)】(均值滤波器、中值滤波器、高斯滤波器、双边滤波器)
  12. word java_java操作word
  13. 合作:对应fork来的项目进行修改操作
  14. 数据分析从0到1之AARRR模型 - Blog2
  15. 计算机毕业设计SSM仿咸鱼二手物品交易系统【附源码数据库】
  16. 调节睡眠周期(有助睡眠)
  17. unimrcp 实现阿里云的plugin
  18. 虚拟机VMware下安装RedHat Linux 9.0 图解
  19. zabbix添加邮件报警机制
  20. python英文诗歌统计_Python-Data-mining-Tutorial

热门文章

  1. 开源!《模式识别与机器学习(PRML)》笔记、代码、NoteBooks 发布
  2. button 样式_实战PyQt5: 111-可以使用QSS样式表的部件
  3. TRzCheckTree
  4. 在markdown编辑模式中打出彩色的文字
  5. 程序员面试系列——单链表的反转
  6. springboot单元测试中@Autowired自动注入的类一直是null
  7. zcmu-1643 报数游戏
  8. Tutorial on Variational AutoEncoders
  9. Android framwork service添加(manager 远程调service,service jni调native code)
  10. Android系统启动流程分析之安装应用