Choosing Capital for Treeland
######################EDITORIAL########################
Arbitrarily root the tree at some vertex, say vertex 1. Now, all the edges are oriented either up (towards the root) or down (away from it). We will call upwards oriented edges red, and downwards oriented edges green. Now, with a single depth-first search, for each vertex, calculate its distance from the root (in number of edges) and the number of red edges along the path to the root. Also, count the number of red edges in the entire tree.
Actually when we are traversing down the line we are looking for coming back in the opposite path. Hence all green branches should be red and all red branches should be turned green.
Now comes the interesting part: Observe that all edges outside the path from the root to vert should turn green, and those on the path should turn red.
The number of edges that need to be flipped if vert is chosen as a capital is given by:
RedEntireTree-- 2*RedOnPath[vert] + RootDistance[vert]This formula can be interpreted as (length of the path-number of red along the path)+(total amount of red -red along the path). The first part of the formula is the number of green edges on the path and the second part of the formula is the number of red edgesthat are not in the path . The summation of the two gives the total changes.
######################EDITORIAL#####################################################
#include<iostream>
using namespace std;
#include<bits/stdc++.h>
list<pair<int,int> > li[10000001];
int red=0;
int blue=0;
int dist[1000001];
int vis[10000001];
int ans[10000001];
int pr[1000000];
int bfs(int start)
{
vis[start]=1;
queue<pair<pair<int,int>,int > > q;
q.push(make_pair(make_pair(start,0),0));
while(!q.empty())
{
int start=q.front().first.first;
int dd=q.front().first.second;
int colour=q.front().second;
q.pop();
list<pair<int,int> > :: iterator it;
for(it=li[start].begin();it!=li[start].end();it++)
{
if(it->second==1 && vis[it->first]==0)
{
dist[it->first]=dd+1;
vis[it->first]=1;
red++;
pr[it->first]=colour+1;
q.push(make_pair(make_pair(it->first,dd+1),colour+1));
}
else if(vis[it->first]==0)
{
pr[it->first]=colour;
vis[it->first]=1;
dist[it->first]=dd+1;
q.push(make_pair(make_pair(it->first,dd+1),colour));
}
}
}
}
int main()
{
int n;
cin>>n;
int a,b;
for(int i=0;i<n-1;i++)
{
cin>>a>>b;
li[a].push_back(make_pair(b,0));
li[b].push_back(make_pair(a,1));
}
bfs(1);
int min=10000001;
for(int i=1;i<=n;i++)
{
ans[i]=red-2*pr[i]+dist[i];
if(ans[i]<min) min=ans[i];
}
cout<<min<<endl;
for(int i=1;i<=n;i++)
if(ans[i]==min) cout<<i<<" ";
return 0;
}
No comments:
Post a Comment