hdu4118
題意:
? ? ? 給你一顆無向帶權樹,每個定點上有一個人,問所有定點都不在自己位置上的最長路徑總和是多少..
?
思路:
? ? ? 其實很簡單,貪心的想下,既然要求全局最大,那么對于每一條邊用的次數越多越好,
? ? ? 給你一顆無向帶權樹,每個定點上有一個人,問所有定點都不在自己位置上的最長路徑總和是多少..
?
思路:
? ? ? 其實很簡單,貪心的想下,既然要求全局最大,那么對于每一條邊用的次數越多越好,
對于每一條邊 ans += ?他的權值*min(他左邊點的個數,有邊點的個數)//為了保證每一個都在邊的另一面找到位置,最后輸出ans * 2,因為是雙向的,a ->b 那么 b ->a ,還有一個就是爆棧,杭電上好像是遞歸多少次后就默認是你無限遞歸了,所以加上防止爆棧的那句就行了...
#pragma comment(linker, "/STACK:1024000000,1024000000") #include<stdio.h> #include<string.h>#define N_edge 200000 + 100 #define N_node 100000 + 100 typedef struct {int from ,to ,next;__int64 cost; }STAR;STAR E[N_edge]; int list[N_node] ,tot; __int64 ge[N_node];void add(int a ,int b ,__int64 c) {E[++tot].from = a;E[tot].to = b;E[tot].cost = c;E[tot].next = list[a];list[a] = tot; }__int64 minn(__int64 a ,__int64 b) {return a < b ? a : b; }__int64 DFS(int s ,int fa) {__int64 sum = 0;for(int k = list[s] ;k ;k = E[k].next){ int to = E[k].to; if(to == fa) continue;sum += DFS(to ,s);}ge[s] = sum;return sum + 1; }int main () {int n ,i ,a ,b ,t ,cas = 1;__int64 c;scanf("%d" ,&t);while(t--){scanf("%d" ,&n);memset(list ,0 ,sizeof(list));tot = 0;for(i = 1 ;i <= n - 1 ;i ++){scanf("%d %d %I64d" ,&a ,&b ,&c);add(a ,b ,c);add(b ,a ,c);}memset(ge ,0 ,sizeof(ge));DFS(1 ,-1);__int64 sum = 0;for(i = 1 ;i <= tot ;i += 2){a = E[i].from;b = E[i].to;c = E[i].cost;if(ge[a] < ge[b]){a = a + b;b = a - b;a = a - b;}sum += minn(ge[b] + 1 ,n - ge[b] - 1) * c;}printf("Case #%d: %I64d\n" ,cas ++ ,sum * 2);}return 0; }
總結
- 上一篇: hdu1428 spfa+记忆化搜索
- 下一篇: hdu4022 map+multiset