Codeforces Round #513 by Barcelona Bootcamp (rated, Div. 1 + Div. 2)-E. Sergey and Subway
阿新 • • 發佈:2018-12-15
思路:題目大意為,將樹距離為2的兩點間加一條線段使其距離為1,求任意兩點的最短距離之和
首先對於一顆樹中任意兩點的距離和Sum是可以DFS一遍求出來的,關鍵是題目附加的條件如何處理。對於兩點距離s為偶數時,它修改後的距離為s/2,而s為奇數時,修改後距離為 s/2+1,因此只要找出兩點距離為奇數的個數s1即可,而對於一顆樹,從根節點開始分層,在偶數層的節點到奇數層的節點間的距離一定就是奇數,因此找出位於奇數,偶數層的點個數即可,這個同樣可以在DFS中一遍求出
Code:
#include<iostream> #include<vector> using namespace std; typedef long long LL; const int MAX_N=200005; LL n,ans; LL cnt[2]; vector<int> e[MAX_N]; LL DFS(int id,int pre,int col); int main() { ios::sync_with_stdio(false); cin>>n; int u,v; for(int i=1;i<n;++i) { cin>>u>>v; e[u].push_back(v); e[v].push_back(u); } DFS(1,0,0); ans=(ans+cnt[0]*cnt[1])/2; cout<<ans<<endl; return 0; } LL DFS(int id,int pre,int col) { col=(col+1)%2; ++cnt[col]; LL sum=1; for(auto c:e[id]) if(c!=pre) sum+=DFS(c,id,col); ans+=sum*(n-sum); return sum; }