图论:树的直径
我真是被自己菜哭了,只记住了两边BFS,还想着复习一下BFS怎么写来着
写完之后整个人都不好了,这是带权图的,丫的
立刻改成了SPFA,希望不要再犯这种错误
1A还是很愉快的
然后例题是一道骗小孩的题,给了个假数k,我还想着不用能不能A呢
结果还是很好了
题意:
有一颗n个结点的带权的无向树,
在s结点放两个机器人, 这两个机器人会把树的每条边都走一遍,
但是最后机器人不要求回到出发点. 问你两个机器人走的路总长之和的最小值是多少
结论是2倍的边权之和减去树的直径
这个题的意思好像是一起走算一次计数
所以刚开始沿着树的直径去走就可以了
或者走到一定程度汇合然后走树的直径,然后再乱走
树的直径的最简单求法是先任意选一个点求SPFA,然后统计最远点,从最远点出发再求SPFA,再统计最远距离就是了
然后这里直接给出程序,因为实在是太太太太太熟了,4年前的板子题
1 #include<cstdio> 2 #include<algorithm> 3 #include<cstring> 4 using namespace std; 5 const int maxn=100005; 6 const int maxm=200005; 7 int n,k,ans; 8 9 int cnt; 10 int g[maxn]; 11 struct Edge{int t,w,next;}e[maxm]; 12 void addedge(int u,int v,int w) 13 { 14 cnt++; 15 e[cnt].t=v;e[cnt].w=w; 16 e[cnt].next=g[u];g[u]=cnt; 17 } 18 19 bool inq[maxn]; 20 int q[maxn],d[maxn]; 21 void spfa(int s) 22 { 23 memset(d,127,sizeof(d)); 24 d[s]=0; 25 int h=0,t=1; 26 q[t]=s; 27 while(h!=t) 28 { 29 h=h%maxn+1; 30 int x=q[h]; 31 inq[x]=0; 32 for(int tmp=g[x];tmp;tmp=e[tmp].next) 33 { 34 if(d[e[tmp].t]>d[x]+e[tmp].w) 35 { 36 d[e[tmp].t]=d[x]+e[tmp].w; 37 if(!inq[e[tmp].t]) 38 { 39 inq[e[tmp].t]=1; 40 t=t%maxn+1; 41 q[t]=e[tmp].t; 42 } 43 } 44 } 45 } 46 } 47 48 int main() 49 { 50 int x,y,z; 51 scanf("%d%d",&n,&k); 52 for(int i=1;i<n;i++) 53 { 54 scanf("%d%d%d",&x,&y,&z); 55 addedge(x,y,z); 56 addedge(y,x,z); 57 ans+=z; 58 } 59 spfa(1); 60 int tmp1=0,tmp2=0; 61 for(int i=1;i<=n;i++) 62 { 63 if(d[i]>tmp2) 64 {tmp2=d[i];tmp1=i;} 65 } 66 spfa(tmp1); 67 tmp1=tmp2=0; 68 for(int i=1;i<=n;i++) 69 { 70 if(d[i]>tmp2) 71 {tmp2=d[i];tmp1=i;} 72 } 73 ans*=2; 74 ans-=tmp2; 75 printf("%d\n",ans); 76 return 0; 77 }
我对简单题还是很有信心的,就是就是,千万要慎重,不要翻车,不要翻车,不要翻车