LightOJ-1094 求树直径,水
题意:给出一棵树求直径。
总结:搜两次即可。先任意找一个点为根找到离它最远的点,再以这个点为根找离它最远的距离。
// LightOJ-1094 #include<iostream> #include<cstdio> #include<cstdlib> #include<algorithm> #include<cstring> #include<string> #include<cmath> #include<queue> #include<stack> #include<map> #include<bitset> #include<vector> #include<set> using namespace std; #pragma comment(linker, "/STACK:102400000,102400000") #define F(i,a,b) for (int i=a;i<b;i++) #define FF(i,a,b) for (int i=a;i<=b;i++) #define mes(a,b) memset(a,b,sizeof(a)) #define INF 0x3f3f3f3f typedef long long ll; const int N = 1e5+10; int T, cas, n, tot, dis[N], head[N], vis[N]; struct Edge { int to, next, w; }edge[N]; void Addedge(int u, int v, int w) { edge[tot].to=v; edge[tot].w=w; edge[tot].next=head[u]; head[u]=tot++; } void dfs(int u) { vis[u]=1; for(int e=head[u]; e!=-1; e=edge[e].next) { int v=edge[e].to, w=edge[e].w; if(vis[v]==0) { dis[v]=dis[u]+w; dfs(v); } } } void Solve() { dfs(0); int mi, maxn=-INF; FF(i,0,n-1) if(maxn<dis[i]) maxn=dis[i], mi=i; mes(dis, 0); mes(vis, 0); dfs(mi); FF(i,0,n-1) if(maxn<dis[i]) maxn=dis[i], mi=i; printf("Case %d: %d\n", cas, maxn); } int main() { scanf("%d", &T); for(cas=1; cas<=T; cas++) { tot=0; mes(vis, 0); mes(dis, 0); mes(head, -1); scanf("%d", &n); FF(i,1,n-1) { int u, v, w; scanf("%d%d%d", &u, &v, &w); Addedge(u, v, w); Addedge(v, u, w); } Solve(); } return 0; }