小q最近學習了一些圖論知識。根據課本,有如下定義。樹:無迴路且連通的無向圖,每條邊都有正整數的權值來表示其長度。如果一棵樹有n個節點,可以證明其有且僅有n-1 條邊。
路徑:一棵樹上,任意兩個節點之間最多有一條簡單路徑。我們用 dis(a,b)表示點a和點b的路徑上各邊長度之和。稱dis(a,b)為a、b兩個節點間的距離。
直徑:一棵樹上,最長的路徑為樹的直徑。樹的直徑可能不是唯一的。
現在小q想知道,對於給定的一棵樹,其直徑的長度是多少,以及有多少條邊滿足所有的直徑都經過該邊。
輸入格式:
第一行包含乙個整數n,表示節點數。 接下來n-1行,每行三個整數a, b, c ,表示點 a和點b之間有一條長度為c的無向邊。
輸出格式:
共兩行。第一行乙個整數,表示直徑的長度。第二行乙個整數,表示被所有直徑經過的邊的數量。
輸入樣例#1:複製
63 1 1000
1 4 10
4 2 100
4 5 50
4 6 100
輸出樣例#1:複製
1110
2【樣例說明】 直徑共有兩條,3 到2的路徑和3到6的路徑。這兩條直徑都經過邊(3, 1)和邊(1, 4)。
對於100%的測試資料:2<=n<=200000,所有點的編號都在1..n的範圍內,邊的權值<=10^9。
這道題目比較玄學。
我們知道對一顆樹不止一條直徑,那麼被所有直徑經過的邊,
隨著直徑的分叉而不斷收縮。
而直徑的分叉點一定是在直徑上的。
但是我並不知道為什麼要從起點推一遍收縮的一段,再從樹的直徑的末尾推一遍收縮的另一端。這兩段之間的路徑就是解。
但是一遍迴圈是推不出的,必須迴圈兩次??
如果有巨佬乙個迴圈搞出了兩個段點可以告訴本蒟蒻qwq。
#include#include#include#include#include#define ll long long
using namespace std;
const int n=200001;
ll dis[n],maxx,s,t;
ll n,m,num,head[n],vis[n];
struct nodee[n<<1];
ll dep[n],ff[n],l,r,ans,son[n];
void add(int from,int to,ll v)
ll read()
while(ch>='0'&&ch<='9')x=x*10+ch-'0',ch=getchar();
return x*w;
}void dfs(int x,int fa)
}void dfs2(int u,int fa)
dep[u]=maxn;
}int main()
dfs(s,0);maxx=0;
for(int i=1;i<=n;i++)if(dis[i]>maxx)maxx=dis[i],t=i;
printf("%lld\n",maxx);
l=t;r=s;
int now=t;
while(now!=s)
now=t;
while(now!=s)
now=s;
while(now)
while(l!=r&&l)
printf("%lld\n",ans);
return 0;
}
SDOI2013 直徑(樹的直徑必經邊)
題目傳送 sol 先求出任一直徑同時把直徑拎出來,樹的非直徑部分全部掛在直徑上 如下 對於直徑上的每乙個點i,如果存在它到非直徑上點的最大距離 g i 等於它到直徑兩端點中較短的那一段 d i 則說明這一段也可以成為直徑中的一部分。而我們需要得到所有直徑的交,畫圖可以發現假設兩端 以中點為界 都存在...
SDOI2013 刺客信條
故事發生在1486 年的義大利,ezio 原本只是乙個文藝復興時期的貴族,後來因為家族成員受到聖殿騎士的殺害,決心成為一名刺客。最終,憑藉著他的努力和出眾的天賦,成為了傑出的刺客大師,他不僅是個身手敏捷的武林高手,飛簷走壁擅長各種暗殺術。刺客組織在他的帶領下,為被剝削的平民聲張正義,趕跑了原本統治義...
SDOI2013 保護出題人
出題人銘銘認為給sdoi2012 出題太可怕了,因為總要被罵,於是他又給sdoi2013 出題了。參加sdoi2012 的小朋友們釋放出大量的殭屍,企圖攻擊銘銘的家。而你作為sdoi2013的參賽者,你需要保護出題人銘銘。殭屍從唯一一條筆直道路接近,你們需要在銘銘的房門前放置植物攻擊殭屍,避免殭屍碰...