NEUACM1132: Renew MST Quickly 增量最小生成树
题目链接:http://acm.neu.edu.cn/hustoj/problem.php?id=1132
和UVa11354很类似
题意:
原先有一棵树,每次加一条边,看最小生成树大小;
这个和增量最小生成树,还是有一点点差别的,就是,正版增量最小生成树,是每次加入一条边后,删掉那个换里面的最大权,当然这里没有这个;
每次的找LCA,我猜可能LCA都会超时吧,没事过,也有可能可以,但是,因为是一直是之前的那棵树,还不如一次性算出来dis i 到 j 的最长路;
1 #include <bits/stdc++.h> 2 3 using namespace std; 4 5 const int maxn = 1000 + 5; 6 7 struct Edge 8 { 9 int from,to,dist; 10 }; 11 12 vector<Edge> G[maxn]; 13 int pa[maxn]; 14 bool vis[maxn]; 15 int dis[maxn][maxn]; 16 17 void dfs(int u,int fa) 18 { 19 int d = G[u].size(); 20 for(int i=0; i<d; i++) 21 { 22 int v = G[u][i].to; 23 if(v!=fa) 24 dfs(v,pa[v]=u); 25 } 26 } 27 28 void _dfs(int k,int cur,int cost) { 29 vis[cur] = 1; 30 31 int d = G[cur].size(); 32 for(int i=0;i<d;i++) { 33 if(!vis[G[cur][i].to]) { 34 dis[k][G[cur][i].to] = max(cost,max(dis[k][G[cur][i].to],G[cur][i].dist)); 35 int v = G[cur][i].to; 36 _dfs(k,v,dis[k][v]); 37 } 38 } 39 40 } 41 42 int main() 43 { 44 int n; 45 int kase = 0; 46 while(scanf("%d",&n)!=EOF) 47 { 48 printf("Test #%d\n",++kase); 49 50 for(int i=0;i<n;i++) 51 G[i].clear(); 52 53 int sum = 0; 54 for(int i=0; i<n-1; i++) 55 { 56 int u,v,d; 57 scanf("%d%d%d",&u,&v,&d); 58 u--; 59 v--; 60 sum+=d; 61 G[u].push_back((Edge) 62 { 63 u,v,d 64 }); 65 G[v].push_back((Edge) 66 { 67 v,u,d 68 }); 69 dis[u][v] = d; 70 dis[v][u] = d; 71 } 72 pa[0] = -1; 73 dfs(0,-1); 74 75 for(int i=0;i<n;i++) { 76 memset(vis,0,sizeof(vis)); 77 vis[i] = 1; 78 _dfs(i,i,0); 79 } 80 81 int q; 82 scanf("%d",&q); 83 84 while(q--) 85 { 86 memset(vis,0,sizeof(vis)); 87 int u,v,d; 88 scanf("%d%d%d",&u,&v,&d); 89 u--; 90 v--; 91 92 int maxx = 0; 93 94 maxx = dis[u][v]; 95 96 if(maxx>d) 97 printf("%d\n",sum-maxx+d); 98 else printf("%d\n",sum); 99 100 } 101 } 102 103 return 0; 104 }