地址:http://codeforces.com/contest/1060/problem/E
思路:题目大意为,将树距离为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;
}