贪心及其证明
设 A , B A,B A,B 为树直径的端点 , , , D i s t x , y Dist_{x,y} Distx,y 为树上两点的距离 , , , 则答案为 ∀ x , y , k ∈ T , max ( min ( D i s t x , k , D i s t y , k ) + D i s t x , y ) . \forall x,y,k\in T,\max(\min(Dist_{x,k},Dist_{y,k})+Dist_{x,y}). ∀x,y,k∈T,max(min(Distx,k,Disty,k)+Distx,y).
分两种情况证明 , , , 其中 A , B A,B A,B 为直径的两个端点 , , , F F F 为出发点 . . .
- 如下图
,
,
, 若两条链有交集
:
:
:

有定义可知
:
:
:
a
+
b
≥
c
+
d
a
+
b
≥
b
+
c
o
r
b
+
d
a
+
b
≥
a
+
c
o
r
a
+
d
a+b \ge c+d\\ a+b \ge b+c~or~b+d\\ a+b\ge a+c~or~a+d
a+b≥c+da+b≥b+c or b+da+b≥a+c or a+d
整理得
:
:
:
a
≥
c
o
r
d
b
≥
c
o
r
d
a\ge c~or~d\\ b\ge c~or~d
a≥c or db≥c or d
显然待证式成立
.
.
.
- 如下图
,
,
, 若两条链无交集
:
:
:

那么同理 : : :
a ≥ e + d o r e + c b ≥ e + d o r e + c a\ge e+d~or~e+c\\ b\ge e+d~or~e+c a≥e+d or e+cb≥e+d or e+c
显然待证式成立 . . .
C + + C++ C++ 实现 : : :
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
template<typename Typename,int MaxCnt>
struct Queues{
private:
Typename Data[MaxCnt];
int head,tail,size;
public:
Queues(){
memset(Data,0,sizeof(Data));
head=tail=size=0;
}
inline void Clear(){
head=tail=size=0;
}
inline void Push(const Typename&x){
if(size==MaxCnt)puts("Error Queue");
else{
size++;
Data[tail]=x;
tail++;
if(tail==MaxCnt)tail=0;
}
}
inline void Pop(){
if(size==0)puts("Error Queue");
else{
size--;
head++;
if(head==MaxCnt)head=0;
}
}
inline Typename Front(){
if(size==0){puts("Error Queue");return Typename();}
else return Data[head];
}
inline bool Empty(){return(size==0);}
inline int Size(){return size;}
};
template<typename TypenameC,int MaxN,int MaxM>
struct Graphs{
typedef TypenameC costtype;
int Last[MaxN],cntn;
int Next[MaxM],To[MaxM],cntm;
costtype Cost[MaxM];
Graphs(){
Clear();
}
inline void Clear(){
cntn=cntm=0;
memset(Last,-1,sizeof(Last));
}
};
template<typename Typename>
inline Typename Min(const Typename&x,const Typename&y){
if(x<y)return x;return y;
}
template<typename Typename>
inline Typename Max(const Typename&x,const Typename&y){
if(x>y)return x;return y;
}
template<typename Typename>
inline void Swap(Typename&x,Typename&y){
Typename t=x;x=y;y=t;
}
template<typename TypenameG>
inline void Insert(TypenameG&G,int from,int to,typename TypenameG::costtype cost){
G.To[G.cntm]=to;G.Cost[G.cntm]=cost;
G.Next[G.cntm]=G.Last[from];G.Last[from]=G.cntm++;
}
const int MaxN=2e5+1e4;
const int MaxM=4e5+1e4;
Graphs<long long,MaxN,MaxM>G;
Queues<int,MaxN>Q;
bool Visit[MaxN];
inline int Bfs(int start,long long *Arr){
memset(Visit,false,sizeof(Visit));
Q.Clear();Q.Push(start);
int res=start;Arr[start]=0;
while(!Q.Empty()){
int from=Q.Front();Q.Pop();
Visit[from]=true;
for(register int k=G.Last[from];k!=-1;k=G.Next[k]){
if(Visit[G.To[k]])continue;
Arr[G.To[k]]=Arr[from]+G.Cost[k];
Q.Push(G.To[k]);
}
if(Arr[res]<Arr[from])res=from;
}
return res;
}
long long Dist[MaxN],DistS[MaxN],DistT[MaxN];
int n,m;
inline void ReInit(){
memset(Dist,0,sizeof(Dist));
memset(DistS,0,sizeof(DistS));
memset(DistT,0,sizeof(DistT));
scanf("%d%d",&n,&m);
for(register int i=1,x,y;i<=m;i++){
long long w;
scanf("%d%d%lld",&x,&y,&w);
Insert(G,x,y,w);Insert(G,y,x,w);
}
}
inline void Work(){
int s=Bfs(1,Dist);
int t=Bfs(s,Dist);
Bfs(s,DistS);
Bfs(t,DistT);
long long ans=0;
for(register int i=1;i<=n;i++)
ans=Max(Min(DistS[i],DistT[i])+Dist[t],ans);
printf("%lld\n",ans);
}
int main(){
ReInit();
Work();
return 0;
}
4万+



被折叠的 条评论
为什么被折叠?



