hdu 4679 Terrorist’s destroy 树的直径+dp
2013-08-19 18:51
344 查看
题意:给你一棵树,每条边都有值W,然后问你去掉一条边,令val = w*max(两颗新树的直径),求val最小值~
做法,先求树的直径,然后算出直径上每个点的最长枝条长度。这样对于每一条边,假如是枝条边,那么val = w*直径,如果不是那么val = max(w*(两颗新树的直径))。新树直径说到这里已经很好算了。
DFS爆栈了一下午
View Code
做法,先求树的直径,然后算出直径上每个点的最长枝条长度。这样对于每一条边,假如是枝条边,那么val = w*直径,如果不是那么val = max(w*(两颗新树的直径))。新树直径说到这里已经很好算了。
DFS爆栈了一下午
#include <stdio.h> #include <string.h> #include <iostream> #include <algorithm> #include <stdlib.h> #include <vector> #include <queue> #include <stack> #define loop(s,i,n) for(i = s;i < n;i++) #define cl(a,b) memset(a,b,sizeof(a)) #pragma comment(linker, "/STACK:1024000000,1024000000") const int maxn = 100005; using namespace std; struct edge { int u,v,w,next; }edges[2*maxn]; struct node { int step,u,v; }q[maxn*2]; int maxp,cnt,n; bool vis[maxn],is_on[maxn]; int set[maxn],head[maxn],dep[maxn],rdp[maxn],trans[maxn],rtrans[maxn],rp[maxn],lp[maxn]; void init() { int i; for(i = 0;i <= n;i++) vis[i] = 0,head[i] = -1,is_on[i] = 0,rdp[i] = 0; cnt = maxp= 0; dep[0] = -1; } void addedge(int u,int v,int w) { int i; edges[cnt].u = u; edges[cnt].v = v; edges[cnt].w = w; edges[cnt].next = head[u]; head[u] = cnt; cnt++; } void dfs(int u,int deep,int pre) { set[u] = pre; vis[u] = true; dep[u] = deep; if(dep[maxp] < dep[u]) maxp = u; // printf("*****u*** %d ***\n",u); int i; for(i = head[u];i != -1;i = edges[i].next) { int v; v = edges[i].v; if(vis[v] == false) { dfs(v,deep+1,u); } } } void bfs(int s) { int i; int maxs = 0; int r,f; f = r = 0; struct node st; st.u = s; st.step = 0; set[s] = -1; q[r++] = st; vis[s] = 1; while(f < r) { struct node tmp; tmp = q[f]; f++; int i; for(i = head[tmp.u];i != -1;i = edges[i].next) { int v; v = edges[i].v; if(!vis[v]) { struct node t; t.u = v; t.step = tmp.step+1; if(maxs < t.step) maxp = v,maxs = t.step; vis[v] = true; set[v] = tmp.u; dep[v] = t.step; q[r++] = t; } } } } int main() { int t,icase; //freopen("data.txt","r",stdin); //freopen("data1.txt","w",stdout); scanf("%d",&t); icase = 0; while(t--) { // int n; int i,j,u,v,w; printf("Case #%d: ",++icase); scanf("%d",&n); init(); loop(0,i,n-1) { scanf("%d %d %d",&u,&v,&w); addedge(u,v,w); addedge(v,u,w); } // dfs(1,0,-1); bfs(1); for(i = 0;i <= n;i++) vis[i] = false; int tmp; tmp = maxp; maxp = 0; //dfs(tmp,0,-1); bfs(tmp); // /* int num; num = 0; while(maxp != -1) { is_on[maxp] = 1; trans[++num] = maxp;//没有初始化 rtrans[maxp] = num; maxp = set[maxp]; } for(i = 1;i <= n;i++) {// if(!is_on[i]) { u = i; while(!is_on[u]) { u = set[u]; } if(rdp[u] < dep[i] - dep[u]) { rdp[u] = dep[i]-dep[u]; } } } for(i = 1;i <= num;i++) { if(i == 1) rp[i] = rdp[trans[i]]; else rp[i] = max(rp[i-1],i-1+rdp[trans[i]]); } for(i = num;i >= 1;i--) { if(i == num) lp[i] = rdp[trans[i]]; else lp[i] = max(lp[i+1],num-i+rdp[trans[i]]); } int ans,ansb; ans = 100000000; ansb = -1; for(i = 0;i < cnt;i+=2) { u = edges[i].u; v = edges[i].v; w = edges[i].w; int subans; if(is_on[u] && is_on[v]) { if(rtrans[u] > rtrans[v]) { int tmp; tmp = u,u = v,v =tmp; } subans = max(rp[rtrans[u]],lp[rtrans[v]]); if(ans > w*subans) ans = w*subans,ansb = i/2+1; } else { if(ans > w*(num-1)) ans = w*(num-1),ansb = i/2+1; } } //*/ // printf("%d\n",ansb); } return 0; }
View Code
相关文章推荐
- 【解题报告】HDU 4679 Terrorist’s destroy -- 树形dp 删一边求两子树直径
- HDU 4679 Terrorist’s destroy (2013多校8 1004题 树形DP)
- HDU 4679 Terrorist’s destroy(树形dp | 多校8)
- HDU 4679 Terrorist’s destroy (树形DP)
- hdu 4679 Terrorist’s destroy(树形DP)
- hdu 4679 Terrorist’s destroy 树形DP
- HDU 4679 Terrorist’s destroy (树形DP)
- hdu 4679 Terrorist’s destroy 树形dp水题 (2013多校联合)
- HDU-4679 Terrorist’s destroy 树形DP,维护
- hdu 4679 Terrorist’s destroy(树形dp)
- hdu 4679 Terrorist’s destroy (树形dp)
- HDU 4679 Terrorist’s destroy (拆边+树的直径)
- HDU 4679 Terrorist’s destroy
- hdu 4679 Terrorist’s destroy
- hdu 4679 Terrorist’s destroy 多校第八场
- HDU 4679 Terrorist’s destroy【Tree】
- 2013多校联合8 1004 Terrorist’s destroy(hdu 4679)
- HDU-4679-树的直径(树形dp)
- HDU 4679 Terrorist’s destroy 解题报告
- hdu-4679-Terrorist’s destroy