Gym
来源:互联网 发布:保利投资顾问待遇知乎 编辑:程序博客网 时间:2024/06/03 18:59
传送门
//思路 : 先根据题意知道肯定是先要强联通缩点, 然后分析题意知道, 要使最远的距离的最小, 就要想到树的直径. 因为树的直径端点到树上的点的距离才最远, 然后要最小那么就枚举一下就行了.
AC Code
/** @Cain*/const int maxn=2e5+5;int dfn[maxn],low[maxn],bel[maxn];int head[maxn],cut[maxn],in[maxn];int pre[maxn];stack<int >S;int cnt,res,ans;int n,m;struct node{ int u,v; ll w;}s[maxn];vector<int >G[maxn];void init(){ Fill(dfn,0);Fill(low,0);Fill(in,0); Fill(bel,0);Fill(s,0);Fill(cut,0); memset(head,-1,sizeof(head)); for(int i=0;i<=n;i++){ G[i].clear(); pre[i] = inf; } cnt = 1;res = 0;}void tarjan(int fa,int u){ dfn[u] = low[u] = cnt++; S.push(u); for(int i=0; i<G[u].size();i++){ int nex = G[u][i]; if(fa == nex ) continue; if(!dfn[nex]){ tarjan(u,nex); low[u] = min(low[u],low[nex]); } else low[u] = min(low[u],dfn[nex]); } if(low[u] == dfn[u]){ res++; while(1){ int v = S.top(); S.pop(); bel[v] = res; pre[res] = min(pre[res],v); if(v == u) break; } }}vector<node >g[maxn];ll dis1[maxn],dis2[maxn];ll max_len; int st,ed;void dd(int u, int fa, ll len,int flag){ //搜索这棵树的直径. if(flag) dis1[u] = len; if(!flag) dis2[u] = len; if(flag && len > max_len) st = u, max_len = len; for(int i = 0; i < g[u].size(); i++) { int v = g[u][i].v; if (v == fa) continue; dd(v, u, len + g[u][i].w, flag); }}void solve(){ scanf("%d%d",&n,&m); init(); for(int i=0;i<m;i++){ int u,v; ll w; scanf("%d%d%lld",&u,&v,&w); s[i].u = u; s[i].v = v; s[i].w = w; G[u].push_back(v); G[v].push_back(u); } tarjan(-1,1); for(int i=0;i<=n;i++) g[i].clear(); for (int i=0 ;i<m; i++){ int u = bel[s[i].u] , v = bel[s[i].v], w = s[i].w; if(u != v){ g[u].push_back((node){0, v, w}); g[v].push_back((node){0, u, w}); } } Fill(dis1,0); Fill(dis2,0); max_len = -1; dd(1, -1, 0, 1); ed = st; max_len = -1; dd(st, -1, 0, 1); swap(st, ed); dd(ed, -1, 0, 0); ll cur = INF; int num = 0; for(int i=1;i<=res;i++){ if(max(dis1[i],dis2[i]) < cur){ cur = max(dis1[i],dis2[i]); num = pre[i]; } if(max(dis1[i],dis2[i]) == cur){ //这里是一个坑点. //要始终保证节点编号最小, 所以还要在可能的答案中选取一个较小的编号. num = min(pre[i],num); } } printf("%d %lld\n",num,cur);}int main(){ int t = 1 ; scanf("%d",&t); while(t--){ // printf("Case %d: ", cas++); solve(); //printf("\n"); }}
阅读全文
0 0
- Gym
- Gym
- Gym
- Gym
- Gym
- Gym
- Gym
- Gym
- Gym
- Gym
- Gym
- Gym
- Gym
- Gym
- Gym
- Gym
- Gym
- Gym
- ant table 扩展 显示html文档 格式化json字符串 并且 实时动态关键字高亮
- mysql触发器
- 多旋翼无人机抛飞实现流程_APM固件
- 堆排序
- SQL 之 cast()函数
- Gym
- fragment懒加载时生命周期分析
- Java中泛型 类型擦除
- 彻底卸载MySQL的方法
- ckeditor 学习笔记【3】粘贴事件/截图粘贴
- Win32串行通信中文版(Serial Communications In Win32)
- HDU5858 Hard problem
- RabbitMQ--RabbitMQ-C客户端使用说明
- 使用jQuery的一些注意事项总结(持续更新......)