light oj 1257 Farthest Nodes in a Tree (II)(724训练题目)主要是利用了反证法: 假设 s-t这条路径为树的直径,或者称为树上的最长路 现有结论,从任意一点
来源:互联网 发布:sql 逐行累加 编辑:程序博客网 时间:2024/05/21 11:10
主要是利用了反证法:
假设 s-t这条路径为树的直径,或者称为树上的最长路
现有结论,从任意一点u出发搜到的最远的点一定是s、t中的一点,然后在从这个最远点开始搜,就可以搜到另一个最长路的端点,即用两遍广搜就可以找出树的最长路
证明:
1 设u为s-t路径上的一点,结论显然成立,否则设搜到的最远点为T则
dis(u,T) >dis(u,s) 且 dis(u,T)>dis(u,t) 则最长路不是s-t了,与假设矛盾
2 设u不为s-t路径上的点
首先明确,假如u走到了s-t路径上的一点,那么接下来的路径肯定都在s-t上了,而且终点为s或t,在1中已经证明过了
所以现在又有两种情况了:
1:u走到了s-t路径上的某点,假设为X,最后肯定走到某个端点,假设是t ,则路径总长度为dis(u,X)+dis(X,t)
2:u走到最远点的路径u-T与s-t无交点,则dis(u-T) >dis(u,X)+dis(X,t);显然,如果这个式子成立,
则dis(u,T)+dis(s,X)+dis(u,X)>dis(s,X)+dis(X,t)=dis(s,t)最长路不是s-t矛盾
附上一张第二种情况的图
这道题让你求出距离每个点最远的点之间距离是多少,因为每个点走的最长路的重点肯定是直径上的某个端点,所以,写个bfs不断的搜吧
#include<cstdio>#include<cstring>#include<iostream>#include<queue>#include<vector>#define N 30005#define in push_backusing namespace std;vector<int>e[N];vector<int>d[N];int k,u,v,w,n,t;int d1[N],d2[N];bool b[N];void bfs(int s,int &t,int w[]){ queue<int>q;int mx=0; memset(b,0,sizeof(b)); memset(w,0,sizeof(w)); q.push(s);b[s]=1;w[s]=0; while(!q.empty()) { int now=q.front();q.pop(); for(int i=0;i<e[now].size();i++) { v=e[now][i];if(b[v])continue; { w[v]=w[now]+d[now][i]; b[v]=1;q.push(v); if(w[v]>mx) mx=w[v],t=v; } } }}int main(){ scanf("%d",&t); k=0; while(t--) { scanf("%d",&n); for(int i=0;i<n;i++) {e[i].clear();d[i].clear();} for(int i=1;i<n;i++) { scanf("%d%d%d",&u,&v,&w); e[u].in(v);e[v].in(u); d[u].in(w);d[v].in(w); } memset(d1,0,sizeof(d1)); memset(d2,0,sizeof(d2)); int x,y; bfs(0,x,d1); bfs(x,y,d1); bfs(y,x,d2); printf("Case %d:\n",++k); for(int i=0;i<n;i++) { printf("%d\n",max(d1[i],d2[i])); } }}
代码来自某大神~~~~
#include <iostream>#include <cstdio>#include <cstring>#include <cmath>#include <algorithm>#include <vector>using namespace std;struct edge{ int v; int w; int next;}edge[60010];int head[30005];int tot = 1;void add(int u,int v,int w){ edge[tot].v=v; edge[tot].next=head[u]; edge[tot].w=w; head[u]=tot++;}int t,n,u,v,w;int vis[30005];int l1[30004],l2[30005];long long cost1[30004],cost2[30004];int num[30004];void dfs(int u,int p){ l1[u]=0; l2[u]=0; cost1[u]=0; cost2[u]=0; for(int i=head[u];i!=-1;i=edge[i].next) { int v=edge[i].v; int w = edge[i].w; if(v==p) continue; dfs(v,u); if(cost2[u]<cost1[v]+w) { cost2[u]=cost1[v]+w; if(cost1[u]<cost2[u]) { // swap(l1[u],l2[u]); swap(cost1[u],cost2[u]); num[u]=v; } } }}void dfs2(int u,int p){ for(int i=head[u];i!=-1;i=edge[i].next) { int v=edge[i].v; int w = edge[i].w; if(v==p) continue; if(v==num[u]) { if(cost2[v]<cost2[u]+w) { cost2[v]=cost2[u]+w; if(cost1[v]<cost2[v]) { // swap(l1[v],l2[v]); swap(cost1[v],cost2[v]); num[v]=u; } } } else { if(cost2[v]<cost1[u]+w) { // l2[v]=l1[u]+1; cost2[v]=cost1[u]+w; if(cost1[v]<cost2[v]) { //swap(l1[v],l2[v]); swap(cost1[v],cost2[v]); num[v]=u; } } } dfs2(v,u); }}int main(){ scanf("%d",&t); int Case = 1; while(t--) { scanf("%d",&n); tot=1; memset(head,-1,sizeof(head)); for(int i=1;i<n;i++) { scanf("%d%d%d",&u,&v,&w); add(u,v,w); add(v,u,w); } dfs(0,-1); dfs2(0,-1); printf("Case %d:\n",Case++); for(int i=0;i<n;i++) { //printf("%d %lld %lld \n",i,cost1[i],cost2[i]); printf("%lld\n",cost1[i]); } } return 0;}
0 0
- light oj 1257 Farthest Nodes in a Tree (II)(724训练题目)主要是利用了反证法: 假设 s-t这条路径为树的直径,或者称为树上的最长路 现有结论,从任意一点
- light oj 1094 Farthest Nodes in a Tree(树的直径模板)
- Light OJ 1094 - Farthest Nodes in a Tree【树的直径 两次bfs】
- Light oj 1094 - Farthest Nodes in a Tree【树的直径】
- Light OJ 1049 Farthest Nodes in a Tree【树的直径】
- Light OJ 1094 Farthest Nodes in a Tree (树的直径)
- Light oj 1094 Farthest Nodes in a Tree(树的最大直径)
- Light-oj-1094 Farthest Nodes in a Tree (树的直径模板题)
- Light OJ 1049 Farthest Nodes in a Tree(树的直径)(模板题)
- 【Light-oj】-1094 - Farthest Nodes in a Tree(树的直径)
- light oj 1094 Farthest Nodes in a Tree(树的直径模板)
- Light OJ 1094 Farthest Nodes in a Tree(树的直径模板)
- 【Light OJ】1049 Farthest Nodes in a Tree(树的直径模板题)
- Light OJ:1094 Farthest Nodes in a Tree(树状DP+统计树的最大直径)
- lightoj 1257 - Farthest Nodes in a Tree (II) 树直径
- LightOJ 1094 - Farthest Nodes in a Tree【树的直径】
- LightOJ - 1094 Farthest Nodes in a Tree(树的直径)
- Farthest Nodes in a Tree(树的直径)
- mysql 的基本命令
- all_of 源码剖析
- ContextLoaderListener作用详解
- plsql连接oracle问题
- java之集合类详解
- light oj 1257 Farthest Nodes in a Tree (II)(724训练题目)主要是利用了反证法: 假设 s-t这条路径为树的直径,或者称为树上的最长路 现有结论,从任意一点
- 【Maven用户手册】Maven之setting.xml配置文件详解
- 简单的HTML学习
- HDU-2010
- 读《What every programmer should know about memory》,小结
- Java的内部类之成员内部类
- C++中隐式转换和显示转换
- H5成长之路 input伪类选择器& vertical-align16-7-25笔记
- 多态ClassCastException:类型转换异常