[APIO 2010] 巡逻
Posted evenbao
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了[APIO 2010] 巡逻相关的知识,希望对你有一定的参考价值。
[题目链接]
https://www.lydsy.com/JudgeOnline/problem.php?id=1912
[算法]
树的直径
[代码]
#include<bits/stdc++.h> using namespace std; #define MAXN 100010 int i,n,l1,l2,tot,u,v,k,now; int head[MAXN],pre[MAXN],d[MAXN]; vector< int > path; pair< int,pair<int,int> > tmp; struct edge { int to,w,nxt; } e[MAXN << 1]; inline void addedge(int u,int v,int w) { tot++; e[tot] = (edge){v,w,head[u]}; head[u] = tot; } inline void dfs1(int u,int fa) { int i,v,w; for (i = head[u]; i; i = e[i].nxt) { v = e[i].to; w = e[i].w; if (v == fa) continue; dfs1(v,u); if (d[u] + d[v] + w > l1) { l1 = d[u] + d[v] + w; tmp = make_pair(i,make_pair(pre[u],pre[v])); } if (d[v] + w > d[u]) { d[u] = d[v] + w; pre[u] = i; } } } inline void dfs2(int u,int fa) { int i,v,w; for (i = head[u]; i; i = e[i].nxt) { v = e[i].to; w = e[i].w; if (v == fa) continue; dfs2(v,u); if (d[u] + d[v] + w > l2) l2 = d[u] + d[v] + w; d[u] = max(d[u],d[v] + w); } } int main() { scanf("%d%d",&n,&k); for (i = 1; i < n; i++) { scanf("%d%d",&u,&v); addedge(u,v,1); addedge(v,u,1); } l1 = 0; memset(d,0,sizeof(d)); dfs1(1,0); now = tmp.second.first; while (now != 0) { path.push_back(now); now = pre[e[now].to]; } path.push_back(tmp.first); now = tmp.second.second; while (now != 0) { path.push_back(now); now = pre[e[now].to]; } for (i = 0; i < path.size(); i++) { e[path[i]].w *= -1; e[path[i] ^ 1].w *= -1; } l2 = 0; memset(d,0,sizeof(d)); dfs2(1,0); if (k == 1) printf("%d ",2 * (n - 1) - l1 + 1); else printf("%d ",2 * n - l1 - l2); return 0; }
以上是关于[APIO 2010] 巡逻的主要内容,如果未能解决你的问题,请参考以下文章