您的位置:首页 > 其它

hdu 4679 Terrorist’s destroy 树的直径+dp

2013-08-19 18:51 344 查看
题意:给你一棵树,每条边都有值W,然后问你去掉一条边,令val = w*max(两颗新树的直径),求val最小值~

做法,先求树的直径,然后算出直径上每个点的最长枝条长度。这样对于每一条边,假如是枝条边,那么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
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: