题目

 题解

思路:

自环重边可以特判然后就变成了找树上的直径最大,答案加1即可

否则这就是一棵基环树,找到这个环,然后求出以环上的每个节点为根的最大直径,然后考虑在环上做贡献。

对于环上的每个点,先求出环的总长summ,显然对于i,与它贡献的点j一定满足,sum[i]表示从起点到i的环上路径长,其中起点可以随便给

然后破环成链,因为求的是最大,直接用单调队列维护即可。至于怎样找环,可以使用拓扑排序,也可以直接DFS

注意

拓扑排序不要写错,先判断这个点是否在环上,然后第二次连边时不要脸度数仍为2的边

#include<bits/stdc++.h>
using namespace std;
#define ll long long
const int MAXN = 1e6 + 3;
inline char GetChar(){static char buf[10001],*p1=buf,*p2=buf;return p1==p2&&(p2=(p1=buf)+fread(buf,1,10001,stdin),p1==p2)?EOF:*p1++;
}
inline void Read(int &n){short f=1;long long x=0;char c=GetChar();while(isdigit(c)==false){if(c=='-'){f=-1;}c=GetChar();}while(isdigit(c)==true){x=((x<<3)+(x<<1)+(c^48));c=GetChar();}n=x*f;
}
struct edge{int v , w;edge(){}edge( int V, int W ){v = V , w = W;}
};
vector<edge>G[MAXN] , G1[MAXN];
int d[MAXN] , n;
queue<int>q;
ll dp[MAXN][2] , maxx , len[MAXN<<1] , dp1[MAXN<<1];
void dfs( int x , int f , int yuan ){for( int i = 0 ; i < G1[x].size() ; i ++ ){int v= G1[x][i].v , w = G1[x][i].w;if( v == f ) continue;dfs( v , x , yuan );if( dp[v][0] + w > dp[x][0] )dp[x][1] = dp[x][0] , dp[x][0] = dp[v][0] + w;else if( dp[v][0] + w > dp[x][1] )dp[x][1] = dp[v][0] + w;}maxx = max( maxx , dp[x][1] + dp[x][0] );
}
void dfs2( int x , int f , int yuan ){for( int i = 0 ; i < G[x].size() ; i ++ ){int v= G[x][i].v , w = G[x][i].w;if( v == f ) continue;dfs2( v , x , yuan );if( dp[v][0] + w > dp[x][0] )dp[x][1] = dp[x][0] , dp[x][0] = dp[v][0] + w;else if( dp[v][0] + w > dp[x][1] )dp[x][1] = dp[v][0] + w;}maxx = max( maxx , dp[x][1] + dp[x][0] );
}
bool vis[MAXN];
int s[MAXN<<1] , ncnt , head , tail , que[MAXN<<1];
int X[MAXN] , Y[MAXN] , W[MAXN];
ll quan;
inline void dfs1( int x , int st , int f ){s[++ncnt] = x;vis[x] = 1;for( int i = 0 ; i < G[x].size() ; i ++ ){int v= G[x][i].v;if( v == f ) continue;if( d[v] == 2 && !vis[v] ){quan += G[x][i].w;dp1[ncnt+1] = dp[v][0];len[ncnt+1] = len[ncnt] + G[x][i].w;dfs1( v , st , x );}else if( v == st ){quan += G[x][i].w;return ;}}
}
int oo[MAXN];
bool cmp( int x , int y ){if( X[x] ^ X[y] )return X[x] < X[y];if( Y[x] ^ Y[y] )return Y[x] < Y[y];return W[x] < W[y];
}
int main(){Read( n );bool fl = 0;for( int i = 1 ; i <= n ; i ++ ){Read( X[i] );Read( Y[i] );Read( W[i] );if( X[i] > Y[i] ) swap( X[i] , Y[i] );oo[i] = i;}sort( oo + 1 , oo + n + 1 , cmp ) ;for( int i = 1 ; i <= n ; i ++ ){if( (X[oo[i]] == X[oo[i-1]] && Y[oo[i]] == Y[oo[i-1]]) || X[oo[i]] == Y[oo[i]] ) { fl = 1; continue;}int x = X[oo[i]] , y = Y[oo[i]] , w = W[oo[i]];d[x] ++ , d[y] ++;G[x].push_back( edge( y , w ) );G[y].push_back( edge( x , w ) );}if( fl ){dfs2( 1 , 0 , 1 );printf( "%lld" , maxx + 1 );return 0;}for( int i = 1;  i <= n ; i ++ ){if( d[i] == 1) {q.push(  i );d[i] --;}}while( !q.empty() ){int x = q.front();q.pop();for( int i = 0 ; i <G[x].size() ; i ++ ){int v= G[x][i].v;d[v] --;if( d[v] == 1 ){q.push( v );d[v] --;}}}for( int i = 1 ; i <= n ; i ++ ){int x = X[i] , y = Y[i] , w = W[i];if( d[x] == 2 || d[y] == 2 ) continue;G1[x].push_back( edge( y , w ) );G1[y].push_back( edge( x , w ) );}for( int i = 1 ; i <= n ; i ++ ){if( d[i] == 2 ){for( int j = 0 ; j < G[i].size() ; j ++ ){int v = G[i][j].v , w = G[i][j].w;if( d[v] == 2 ) continue;dfs( v , i , i );if( dp[v][0] + w > dp[i][0] )dp[i][1] = dp[i][0] , dp[i][0] = dp[v][0] + w;else if( dp[v][0] + w > dp[i][1] )dp[i][1] = dp[v][0] + w;maxx = max( maxx , dp[i][1] + dp[i][0] );}}}for( int i = 1 ; i <= n ; i ++ ){if( d[i] == 2 ){len[1] = 0;dp1[1] = dp[i][0];dfs1( i , i , 0 );break;}}for( int i = 1 ; i <= ncnt ; i ++ ){len[i+ncnt] = len[i] + quan;dp1[i+ncnt] = dp1[i];}ncnt *= 2;int last = 1;head = 1;for( int i = 2 ; i <= ncnt / 2 ; i ++ ){if( ( len[i] - len[1] ) * 2 <= quan ){while( head <= tail && len[que[tail]] + dp1[que[tail]] < len[i] + dp1[i] ) tail --;que[++tail] = i;last = i;}else break;}for( int i = 1 ; i <= ncnt / 2 ; i ++ ){while( head <= tail && ( (len[que[head]] - len[i] ) * 2 > quan || que[head] == i ) ) head ++;last = max( last , i );while( last + 1 <= ncnt && last + 1 != i + ncnt && (len[last+1] - len[i] ) * 2 <= quan ){while( head <= tail && dp1[last+1] + len[last+1] > dp1[que[tail]] + len[que[tail]] ) tail --;que[++tail] = last + 1;last ++;}if( head <= tail )maxx = max( maxx , dp1[i] + dp1[que[head]] + len[que[head]] - len[i] );}printf( "%lld" , maxx + 1 );return 0;
}

冗长无比...

黑暗之魂(JZOJ)相关推荐

  1. JZOJ 5905. 【NOIP2018模拟10.15】黑暗之魂(darksoul)

    Description oi_juruo热爱一款名叫黑暗之魂的游戏.在这个游戏中玩家要操纵一名有 点生命值的无火的余灰在一张地图中探险.地图中有n个篝火(也就是存档点).在篝火处休息可以将生命值恢复满 ...

  2. 【JZOJ A组】黑暗之魂(darksoul)

    Description oi_juruo热爱一款名叫黑暗之魂的游戏.在这个游戏中玩家要操纵一名有 点生命值的无火的余灰在一张地图中探险.地图中有n个篝火(也就是存档点).在篝火处休息可以将生命值恢复满 ...

  3. [树上最长链][tarjan][单调队列][环上前缀和] Jzoj P5905 黑暗之魂(darksoul)

    Description oi_juruo热爱一款名叫黑暗之魂的游戏.在这个游戏中玩家要操纵一名有 点生命值的无火的余灰在一张地图中探险.地图中有n个篝火(也就是存档点).在篝火处休息可以将生命值恢复满 ...

  4. JZOJ 5461 购物 —— 贪心

    题目:https://jzoj.net/senior/#main/show/5461 贪心,原来想了个思路,优先选优惠价最小的 K 个,然后其他按原价排序遍历: 如果当前物品没选过,原价选上,如果选过 ...

  5. 用摩斯电码通关《黑暗之魂3》!up主自制奇葩手柄,连育碧都找上门合作

    博雯 发自 凹非寺 量子位 报道 | 公众号 QbitAI <黑暗之魂3>,一款以玩家受苦为核心卖点全球玩家死亡上亿次的高难动作游戏. 随手打开直播,就可以欣赏到人类受难现场大放送: 但现 ...

  6. JZOJ 5372. 【NOIP2017提高A组模拟9.17】猫

    Description 信息组最近猫成灾了!隔壁物理组也拿猫没办法.信息组组长只好去请神刀手来帮他们消灭猫.信息组现在共有n 只猫(n 为正整数),编号为1 到n,站成了一个环,第i 只猫的左边是第i ...

  7. [jzoj NOIP2018模拟 11.01]

    很庆幸打了这场模拟赛,因为这一场爆零 好像上次纪中的某场比赛我也出现了同样的问题,光是计算时间复杂度而忘记了空间的限制.想必是比上次惨的,考场上就写了两题而这两题都因为MLE爆零了.而且我T2还码了7 ...

  8. 【DP】小学生语文题(jzoj 5102)

    正题 jzoj 5102 题目大意 给你两个串A,B,字母个数相等,可以把B的一个字符移到前面某个位置,问你最少移多少次可以使A,B相等 解题思路 设fi,jf_{i,j}fi,j​为A匹配了i-n, ...

  9. 【二分】防具布置/秦腾与教学评估(ybtoj 二分-1-2/jzoj 1253/luogu 4403)

    正题 ybtoj 二分-1-2 jzoj 1253 luogu 4403 题目大意 给出n组数:si,ei,dis_i,e_i,d_isi​,ei​,di​ 对于每组数据,表示在sis_isi​加1, ...

最新文章

  1. php libev pthreads,libuv 与 libev 的对比
  2. Oracle442个应用场景---------PL/SQL基础
  3. Windows 技术篇-桌面图标全部消失问题解决方法,windows资源管理器重启实例演示
  4. form 多个submit php,一个复杂的PHP表单处理方案?
  5. 在Linux中如何查看文件的修改日期
  6. Responsive Web Design 简单介绍与优缺点、实作入门, 响应式设计
  7. linux 文件系统路径,Linux编程 1 (文件系统路径说明, 目录结构说明)
  8. java 工作流_【JAVA之工作流介绍】
  9. 一个CSharp类代码,让你的窗体显示的更酷(转)
  10. python gui 框架中显示gif_使用QLab在PyQt GUI中显示gif
  11. 父工程的版本号决定上传私服仓库的位置
  12. 【重点 递归构造二叉树】LeetCode 95. Unique Binary Search Trees II
  13. 记录08_7.15~7.16
  14. 微信添加好友提示服务器繁忙,微信添加好友提示操作过于频繁怎么办 微信加人频繁的解决方法...
  15. java调用打印机没反应_java代码调用打印机没反应
  16. Unity 利用Skybox Panoramic着色器制作全景图预览有条缝隙问题解决办法
  17. 海外游戏广告投放操作技巧
  18. 面试官:你说说软件测试WHX模型(图解)
  19. 项目经验分享:基于昇思MindSpore实现手写汉字识别
  20. SpringBoot重点详解--整合hive-jdbc

热门文章

  1. 利用Arcgis地图工具自动输出报告地图图纸
  2. 直方图实例详解(颜色直方图、灰度直方图)
  3. 毕业答辩英文论文如何找
  4. SOLIDWORKS 2023新增功能 - 3D CAD
  5. vsCode中代码保存自动刷新页面,open with live server,可修改打开浏览器
  6. 如何防止无线路由器被蹭网
  7. 了解RISC-V指令集架构
  8. 设置cpu亲和性_如何快速设置一个任务的CPU亲和力?
  9. 计算机组装与维护常见问答题,计算机组装与维护常见问答题
  10. 图上的并行处理 Parallel Processing of Graphs