标签:ace sed isp find ring fine answer bre uil
Terrorist’s destroy HDU - 4679
InputThe first line contains integer T(1<=T<=20), denote the number of the test cases.
For each test cases,the first line contains a integer n(1 < n <= 100000);denote the number of the houses;
Each of the following (n-1) lines contains third integers u,v,w, indicating there is a road between house u and houses v,and will cost terrorist w energy to destroy it.The id of these road is number from 1 to n-1.(1<=u<=n , 1<=v<=n , 1<=w<=10000)OutputFor each test case, output the case number first,and then output the id of the road which the terrorist should destroy.If the answer is not unique,output the smallest id.Sample Input
2 5 4 5 1 1 5 1 2 1 1 3 5 1 5 1 4 1 1 3 1 5 1 1 2 5 1
Sample Output
Case #1: 2 Case #2: 3
题意:给你一棵树和边上的权值,定义去掉一条边的花费为边权值(a)乘上b,b定义为去掉边后形成的两棵树中两点间的最远距离(注意是各自内部的最远距离),问去掉哪条边的花费最少?
#include<cstdio> #include<iostream> #include<algorithm> #include<cstring> #include<sstream> #include<cmath> #include<stack> #include<cstdlib> #include <vector> #include<queue> using namespace std; const int INF = 0x3f3f3f3f; const int maxn = 200020; int q[maxn],dislong[maxn],deleteLeft[maxn],deleteRight[maxn],pre[maxn],father[maxn],dep[maxn]; int list[maxn],Next[maxn],p[maxn],c[maxn],id[maxn],maxx,n; bool b[maxn],inlong[maxn]; int findlong(int xx,int n) { int t,w,now,k,x; for (int i = 1; i <= n; i++) { b[i] = true; } t = 0; w = 1; q[1] = xx; dislong[1] = 1; b[xx] = false; pre[xx] = 0; maxx = 0; while (t < w) { t++; x = q[t]; k = list[x]; while (k > 0) { if (b[p[k]] == true) { w++; b[p[k]] = false; q[w] = p[k]; dislong[w] = dislong[t]+1; pre[p[k]] = x; if (dislong[w] > maxx) {maxx = dislong[w]; now = p[k];} } k = Next[k]; } } return now; } void init(int n) { for (int i = 1; i <= n; i++) { list[i] = 0; } } void dfs_dep(int x,int pre1) { int k; dep[x] = 1; k = list[x]; while (k > 0) { if (inlong[p[k]] == false && p[k] != pre1) { dfs_dep(p[k],x); dep[x] = max(dep[x],dep[p[k]]+1); } k = Next[k]; } } int main() { int t; scanf("%d",&t); int ca = 1; while(t--) { int tot = 0; scanf("%d",&n); init(n); for (int i = 1;i < n; i++) { int u,v,w; scanf("%d%d%d",&u,&v,&w); tot++; Next[tot] = list[u]; list[u] = tot; p[tot] = v; c[tot] = w; id[tot] = i; tot++; Next[tot] = list[v]; list[v] = tot; p[tot] = u; c[tot] = w; id[tot] = i; } if (n != 1) { memset(pre,0,sizeof(pre)); int front = findlong(1,n); int rear = findlong(front,n); int sum = maxx-1; int k = rear; memset(inlong,false,sizeof(inlong)); memset(father,0,sizeof(father)); while (k > 0) { inlong[k] = true; father[pre[k]] = k; k = pre[k]; } memset(dep,0,sizeof(dep)); for(int i=1;i<=n;i++) if(inlong[i]) dfs_dep(i,0); memset(deleteLeft,0,sizeof deleteLeft); memset(deleteRight,0,sizeof deleteRight); k = front; int step = 0; while (k != rear) { step++; deleteLeft[k] = max(deleteLeft[pre[k]],step-1+dep[k]-1); k = father[k]; } k = rear; step = 0; father[rear] = 0; while (k != front) { step++; deleteRight[k] = max(deleteRight[father[k]],step-1+dep[k]-1); k = pre[k]; } //遍历直径 int ans = INF; int result = INF; k = front; int kk; while (k != rear) { kk = list[k]; while (kk > 0) { if (p[kk] == father[k]) break; kk = Next[kk]; } if (ans > c[kk]*max(deleteLeft[k],deleteRight[father[k]])) { ans = c[kk]*max(deleteLeft[k],deleteRight[father[k]]); result = id[kk]; } else if (ans == c[kk]*max(deleteLeft[k],deleteRight[father[k]])) { if (result > id[kk]) result = id[kk]; } k = father[k]; } //遍历枝条 for (int i = 1; i <= n; i++) { k = list[i]; while (k > 0) { if(!(inlong[i] && inlong[p[k]])) { if (ans > c[k]*sum) { ans = c[k]*sum; result = id[k]; } else if (ans == c[k]*sum) { if (result > id[k]) result = id[k]; } } k = Next[k]; } } printf("Case #%d: %d\n",ca++,result); } } return 0; }
Terrorist’s destroy HDU - 4679
标签:ace sed isp find ring fine answer bre uil
原文地址:https://www.cnblogs.com/smallhester/p/10308269.html