hdu 4679 Terrorist’s destroy 树的直径+dp
题意:给你一棵树,每条边都有值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 = ;
using namespace std;
struct edge
{
int u,v,w,next;
}edges[*maxn];
struct node
{
int step,u,v;
}q[maxn*];
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 = ;i <= n;i++)
vis[i] = ,head[i] = -,is_on[i] = ,rdp[i] = ;
cnt = maxp= ;
dep[] = -;
}
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 != -;i = edges[i].next)
{
int v;
v = edges[i].v;
if(vis[v] == false)
{
dfs(v,deep+,u);
}
}
}
void bfs(int s)
{
int i;
int maxs = ;
int r,f;
f = r = ;
struct node st;
st.u = s;
st.step = ;
set[s] = -;
q[r++] = st;
vis[s] = ;
while(f < r)
{
struct node tmp;
tmp = q[f];
f++;
int i;
for(i = head[tmp.u];i != -;i = edges[i].next)
{
int v;
v = edges[i].v;
if(!vis[v])
{
struct node t;
t.u = v;
t.step = tmp.step+;
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 = ;
while(t--)
{
// int n;
int i,j,u,v,w;
printf("Case #%d: ",++icase);
scanf("%d",&n);
init();
loop(,i,n-)
{
scanf("%d %d %d",&u,&v,&w);
addedge(u,v,w);
addedge(v,u,w);
} // dfs(1,0,-1);
bfs(); for(i = ;i <= n;i++)
vis[i] = false;
int tmp;
tmp = maxp;
maxp = ;
//dfs(tmp,0,-1);
bfs(tmp); // /*
int num;
num = ;
while(maxp != -)
{
is_on[maxp] = ; trans[++num] = maxp;//没有初始化
rtrans[maxp] = num;
maxp = set[maxp];
} for(i = ;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 = ;i <= num;i++)
{
if(i == )
rp[i] = rdp[trans[i]];
else
rp[i] = max(rp[i-],i-+rdp[trans[i]]);
}
for(i = num;i >= ;i--)
{
if(i == num)
lp[i] = rdp[trans[i]];
else
lp[i] = max(lp[i+],num-i+rdp[trans[i]]);
}
int ans,ansb;
ans = ;
ansb = -;
for(i = ;i < cnt;i+=)
{
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/+; }
else
{
if(ans > w*(num-))
ans = w*(num-),ansb = i/+;
}
} //*/ //
printf("%d\n",ansb); }
return ;
}
hdu 4679 Terrorist’s destroy 树的直径+dp的更多相关文章
- hdu 4679 Terrorist’s destroy 树形DP
链接:http://acm.hdu.edu.cn/showproblem.php?pid=4679 题意:给定一颗树,每条边有一个权值w,问切掉哪条边之后,分成的两颗树的较大的直径*切掉边的权值最小? ...
- HDU 4679 Terrorist’s destroy (2013多校8 1004题 树形DP)
Terrorist’s destroy Time Limit: 6000/3000 MS (Java/Others) Memory Limit: 65535/32768 K (Java/Othe ...
- HDU 4679 Terrorist’s destroy
如果不在最长路的边,那么肯定是w*最长路. 如果在最长路,那么把最长路分成两段,左边树的最长路就是左段+左边点的次短路(不包含最长路上的点的最长路) ,右边同理. 还有就是更新,经过左端点的最长路,不 ...
- hdu 4607 Park Visit 求树的直径
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4607 题目大意:给你n个点,n-1条边,将图连成一棵生成树,问你从任意点为起点,走k(k<=n) ...
- Hdu 4612 Warm up (双连通分支+树的直径)
题目链接: Hdu 4612 Warm up 题目描述: 给一个无向连通图,问加上一条边后,桥的数目最少会有几个? 解题思路: 题目描述很清楚,题目也很裸,就是一眼看穿怎么做的,先求出来双连通分量,然 ...
- hdu 4123 Bob’s Race 树的直径+rmq+尺取
Bob’s Race Time Limit: 5000/2000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others) Probl ...
- F - Warm up - hdu 4612(缩点+求树的直径)
题意:有一个无向连通图,现在问添加一条边后最少还有几个桥 分析:先把图缩点,然后重构图为一棵树,求出来树的直径即可,不过注意会有重边,构树的时候注意一下 *********************** ...
- HDU 4123 Bob’s Race 树的直径+单调队列
题意: 给定n个点的带边权树Q个询问. 以下n-1行给出树 以下Q行每行一个数字表示询问. 首先求出dp[N] :dp[i]表示i点距离树上最远点的距离 询问u, 表示求出 dp 数组中最长的连续序列 ...
- F - Warm up HDU - 4612 tarjan缩点 + 树的直径 + 对tajan的再次理解
题目链接:https://vjudge.net/contest/67418#problem/F 题目大意:给你一个图,让你加一条边,使得原图中的桥尽可能的小.(谢谢梁学长的帮忙) 我对重边,tarja ...
随机推荐
- WKWebkit使用
webkit使用WKWebView来代替IOS的UIWebView和OSX的WebView,并且使用Nitro JavaScript引擎,这意味着所有第三方浏览器运行JavaScript将会跟safa ...
- Oracle 分组函数
分组函数的介绍 分组函数作用于一组数据,并对一组数据返回一个值. (引用网上的一张图) 分组函数的使用规则 SELECT [column,] group_function(column) FROM t ...
- Spring AOP (事务管理)
一.声明式事务管理的概括 声明式事务(declarative transaction management)是Spring提供的对程序事务管理的方式之一. Spring的声明式事务顾名思义就是采用声明 ...
- Django 部署(Apache下)
前言: 因为需要在服务器下运行python脚本,所以需要搭建Django服务器.所以将自己的学习过程也记录下来,方便日后查阅. 本文环境如下: Ubuntu 16.04 python2.7 Apac ...
- 常用RDD
只作为我个人笔记,没有过多解释 Transfor map filter filter之后,依然有三个分区,第二个分区为空,但不会消失 flatMap reduceByKey groupByKey() ...
- 一个UUID生成算法的C语言实现——WIN32版本
源: 一个UUID生成算法的C语言实现——WIN32版本
- Redis学习笔记之Redis单机,伪集群,Sentinel主从复制的安装和配置
0x00 Redis简介 Redis是一款开源的.高性能的键-值存储(key-value store).它常被称作是一款数据结构服务器(data structure server). Redis的键值 ...
- vue2.0中配置文件路径
在build/webpack.base.conf.js中添加一些代码即可 module.exports = { resolve: { extensions: ['.js', '.vue', '.jso ...
- 20145302张薇 Java第一周学习总结
20145302张薇 <Java程序设计>第一周学习总结 教材学习内容总结 第一章 1995年,java被公认诞生.java第一开始为了消费性数字产品(如手机)而设计,所以java本身有很 ...
- Linux 下部署Django项目
Linux 下部署Django项目 说明:本文所使用的环境为CentOS 6+Python2.7+Django1.11 安装Django.Nginx和uWSGI 1.确定已经安装了2.7版本的Py ...