Description


A国是一个商业高度发达的国家。它包含了n座城市,每座城商业都很发达。但不幸的是,A国的交通并没有像其商业那么发达,它仅仅保证了任意两座城市之间有路径存在,而且只存在唯一的一条!

拥有雄厚经济实力的商人们决定集资修建一条路,但在修建方案上各个商人都希望新建成的道路对自己利益最大。最终他们决定造一条路,使得两个城市间所需经过道路的数量的最大值尽可能小。为此他们提出了很多修建方案,但他们并不知道每一方案新建道路后最远城市间的最大值为多少,他们有多种修建方案,你能告诉他们每一方案对应的最远城市间的最大值吗?

Solution


今天做了一道加强版。。写了3.8k

首先这一定是环套树,答案可以是树上的最长链或者从某一叶子出发跨越环结束于某叶子的路径

先跑连通分量把环抠出来,两次bfs求出每棵树上最长链。我们记以环上节点x为根的子树中以x为起点的最长路径为dis[x],那么跨过环的答案一定形如dis[x]+dis[y]+get_dis(x,y)这样。

我们把环上的点复制一份,那么就可以只考虑顺时针的距离。如果边权为1,下标相减就是两点的距离。如果边权不等,那么前缀和就能算环上点的距离

观察这个柿子。dis[x]+sum[x]是常数,等价于我们要求某一区间内最大的dis[y]-sum[y],这个上单调队列即可

然后可能会有重边和自环。这个就离线排序保留最短边就行了

Code


#include <stdio.h>
#include <string.h>
#include <algorithm>
#include <stack>
#include <vector>
#include <queue>
#include <map>
#define rep(i,st,ed) for (register int i=st;i<=ed;++i)
#define fill(x,t) memset(x,t,sizeof(x))typedef long long LL;
const int N=2000005;struct edge {int x,y,w,next;} e[N*2],g[N*2];int ls[N],fa[N],edCnt=1;
int dfn[N],low[N],bel[N];
int a[N],q[N],col[N],yqw;
int size[N],whf[N],max,n;LL sum[N],dis[N],lxf[N],wjp[N],ans;std:: stack <int> stack;
std:: map <int,bool> map[N];bool vis[N],inq[N],used[N],flag;inline int read() {int x=0,v=1; char ch=getchar();for (;ch<'0'||ch>'9';v=(ch=='-')?(-1):v,ch=getchar());for (;ch<='9'&&ch>='0';x=x*10+ch-'0',ch=getchar());return x*v;
}void add_edge(int x,int y,int w) {e[++edCnt]=(edge) {x,y,w,ls[x]}; ls[x]=edCnt;e[++edCnt]=(edge) {y,x,w,ls[y]}; ls[y]=edCnt;
}void dfs1(int now,int fa) {dfn[now]=low[now]=++dfn[0];vis[now]=true; stack.push(now);for (int i=ls[now];i;i=e[i].next) {if (e[i].y==fa) continue;if (!dfn[e[i].y]) {dfs1(e[i].y,now);low[now]=std:: min(low[now],low[e[i].y]);} else if (vis[e[i].y]) low[now]=std:: min(dfn[e[i].y],low[now]);}if (low[now]==dfn[now]) {int y=0; bel[0]++;while (y!=now) {y=stack.top(); stack.pop();bel[y]=bel[0];size[bel[0]]++;vis[y]=false;}}
}void dfs2(int now,int fa) {a[++a[0]]=now;if (a[0]==yqw) return (void) (flag=true);for (int i=ls[now];i;i=e[i].next) {if (flag) continue;if (!vis[e[i].y]) continue;if (e[i].y==fa) continue;dfs2(e[i].y,now);}
}void dfs3(int now,int c) {col[now]=c;for (int i=ls[now];i;i=e[i].next) {if (col[e[i].y]||vis[e[i].y]) continue;dfs3(e[i].y,c);}
}int bfs(int st) {int ret=0; used[st]=true;std:: queue <int> que;que.push(st); dis[st]=0;for (;!que.empty();) {int now=que.front(); que.pop();if (dis[now]>dis[ret]) ret=now;for (int i=ls[now];i;i=e[i].next) {if (col[e[i].y]==col[st]&&!used[e[i].y]) {dis[e[i].y]=dis[now]+e[i].w;used[e[i].y]=true;que.push(e[i].y);}}}return ret;
}bool cmp(edge a,edge b) {if (a.x==b.x&&a.y==b.y) return a.w<b.w;if (a.x==b.x) return a.y<b.y;return a.x<b.x;
}int main(void) {freopen("data.in","r",stdin);// freopen("myp.out","w",stdout);n=read(); int st,chp=0;rep(i,1,n) {int x=read(),y=read(),w=read();if (x>y) std:: swap(x,y);g[i]=(edge) {x,y,w};}std:: sort(g+1,g+n+1,cmp);rep(i,1,n) {if (g[i].x==g[i].y) {chp=true;continue;}if (g[i].x==g[i-1].x&&g[i].y==g[i-1].y) {chp=true;continue;}add_edge(g[i].x,g[i].y,g[i].w);}if (chp) {int ret=bfs(1);fill(used,0);ans=dis[bfs(ret)];printf("%lld\n", ans+1);return 0;}dfs1(1,0);rep(i,1,n) if (size[bel[i]]!=1) {st=i; ++yqw;vis[i]=true;}dfs2(st,0);rep(i,1,a[0]) dfs3(a[i],i);rep(i,1,a[0]) a[a[0]+i]=a[i];fill(used,0);rep(i,1,a[0]) {max=bfs(a[i]);for (int j=ls[a[i]];j;j=e[j].next) {if (e[j].y==a[i+1]) sum[i+1]=sum[i]+e[j].w;}wjp[i]=dis[max]-sum[i];lxf[i]=dis[max]+sum[i];}fill(used,0);rep(i,a[0]+1,a[0]*2) {max=bfs(a[i-a[0]]);for (int j=ls[a[i]];j;j=e[j].next) {if (e[j].y==a[i+1]) sum[i+1]=sum[i]+e[j].w;}wjp[i]=dis[max]-sum[i];lxf[i]=dis[max]+sum[i];}int h=1,t=1; q[1]=1;rep(i,2,a[0]*2) {while (h<=t&&sum[i]-sum[q[h]]>sum[a[0]+1]/2) h++;if (h<=t) ans=std:: max(ans,lxf[i]+wjp[q[h]]);while (h<=t&&wjp[q[t]]<=wjp[i]) t--;q[++t]=i;}rep(i,1,n) if (size[bel[i]]!=1) {vis[i]=true;} else vis[i]=false;fill(used,0);rep(i,1,a[0]) whf[i]=bfs(a[i]);fill(used,0);rep(i,1,a[0]) {int ret=bfs(whf[i]);ans=std:: max(ans,dis[ret]);}printf("%lld\n", ans+1);return 0;
}

tyvj4878 道路修建 双连通分量+单调队列相关推荐

  1. 单调队列优化的背包问题

    对于背包问题,经典的背包九讲已经讲的很明白了,本来就不打算写这方面问题了. 但是吧. 我发现,那个最出名的九讲竟然没写队列优化的背包.... 那我必须写一下咯嘿嘿,这么好的思想. 我们回顾一下背包问题 ...

  2. 【Leetcode单调队列】- 洛谷P1714切蛋糕

    单调队列 解决该类问题的重点维护一个队列,从队首到队尾是递减的,队首是最大的.队尾是最小的. 队尾接受值,队首排出值. Java实现用双端队列,前面接收值,后面排出来值. 这类题目往往是跟滑动窗口一起 ...

  3. bzoj2500幸福的道路 树形dp+单调队列

    2500: 幸福的道路 Time Limit: 20 Sec  Memory Limit: 256 MB Submit: 434  Solved: 170 [Submit][Status][Discu ...

  4. 双端队列中的单调队列

    1. 双端队列 普通队列是限制仅在队尾进行插入,在队头进行删除操作的线性表,队列的插入叫做入队列,队列的删除叫做出队列. 而双端队列则是放开了这个限制,在队头和队尾两端都可以进行入队和出队操作的队列. ...

  5. Acwing算法基础课学习笔记(四)--数据结构之单链表双链表模拟栈模拟队列单调栈单调队列KMP

    单链表 算法题中最常考的单链表就是邻接表(用来存储图和数),比如最短路问题,最小生成树问题,最大流问题.双链表用于优化某些问题. 利用数组来表达单链表:存储值和指针的两个数组利用下标进行关联. 需要注 ...

  6. 计蒜客 A2232.程序设计:蒜厂年会-单调队列(双端队列(STL deque)实现)滑窗维护最小前缀和...

    程序设计:蒜厂年会 问答问题反馈 只看题面 16.79% 1000ms 262144K 在蒜厂年会上有一个抽奖,在一个环形的桌子上,有 nn 个纸团,每个纸团上写一个数字,表示你可以获得多少蒜币.但是 ...

  7. 【HDU - 3394】Railway(点双连通分量,Tarjan算法,思维tricks)

    题干: There are some locations in a park, and some of them are connected by roads. The park manger nee ...

  8. HDU 3394 Railway(点双连通分量)

    题目大意 一个公园中有 n 个景点,景点之间通过无向的道路来连接,如果至少两个环公用一条路,路上的游客就会发生冲突:如果一条路不属于任何的环,这条路就没必要修 问,有多少路不必修,有多少路会发生冲突 ...

  9. 0x12.基本数据结构 — 队列与单调队列

    目录 一.队列 0.UVA540 团体队列 Team Queue 1.AcWing 133. 蚯蚓(模拟优先队列) 二 .单调队列 0.AcWing 135. 最大子序和(单调队列) 1.luogu ...

最新文章

  1. CVPR2020文章汇总 | 点云处理、三维重建、姿态估计、SLAM、3D数据集等(12篇)
  2. 社区v2022.3版上线:发帖、看直播、评论体验升级,并支持机构号申请
  3. 图解Linux命令实例
  4. shujufenxi:一季度中国人每天存700亿元!“报复性存款”能带来消费吗?
  5. 对map集合进行排序
  6. tomcat运行错误: 无效的源发行版:16
  7. 牛客练习赛 65 (待补E-网络流)
  8. Redis学习总结(18)——Redis 常见的使用场景汇总
  9. 用Not Exists 代替Not In
  10. 人工智能终将自我进化?排除无用功能,让自己更加完美?
  11. 教师对php作品评语通用,教师批改作业100例精彩评语,太有用了!
  12. 中式红木装修——打造适合审美的居住空间
  13. Unity-tweak-tool插件
  14. 计算机ping不通dns,电脑不能上网但是可以Ping通和DNS解析解决办法是什么
  15. mouseinfo的使用
  16. 用cxf开发一个可以被安卓调用的接口
  17. 洛谷 P3959 [NOIP2017]宝藏 题解
  18. 一个看着有用,但是没多大用的IDEA插件MybatisCode
  19. 鹏业云计价i20“小数规则”应用
  20. 大数据产品经理python_大数据岗位要求之数据产品经理

热门文章

  1. 登陆账号时提示“账号登陆中!”该怎么处理呢?
  2. java 开源报表_JAVA 开源报表
  3. SEO站内优化的重点是什么?站内URL应该如何合理优化?
  4. java 类的子类对象_使用超类初始化子类对象Java
  5. 【我的物联网成长记6】由浅入深了解NB-IoT
  6. Android移动开发检测网络状态并使用BroadcastReceiver(广播接收者)进行接收网络变化的后续处理
  7. Linux环境下安装ssh2模块
  8. FreeModbus开源协议栈-mb.c
  9. 无法挣脱的“需求无知” 无法企及的诚实
  10. 解决127.0.0.1拒绝了我们的连接请求