您的位置:首页 > 其它

Codeforces 734E. Anton and Tree By Assassin 缩点+树的最大直径

2016-11-30 19:30 447 查看
题意就不多加赘述了,说白了就是每一次可以反转任意连通块儿,这个连通块儿必须满足相连且花色相同,问你最少的反转次数。

思路:一看题目思路其实很清楚了,我们为了缩小数据规模,利用缩点将一个连同块儿化成一个点,之后我们一定可以得到一个树,因为原题就是一个树,之后我们只需要找到树的最大直径就行了。

步骤1:缩点

步骤2:求树的最大直径(其实就是两次搜索,因为第一次从任意点出发找到最远的一个点,那么这个点一定是树直径上两端的一个点,第二次再从这个点出发找到最远的点的距离就是树的直径了。)

第一次写缩点,丑了点。。。

#include<bits/stdc++.h>
#define input freopen("input.txt","r",stdin)
using namespace std;
const int maxn = 200002;
vector<int>vec[maxn],change[maxn];
int vis[maxn]={0},color[maxn]={0},belong[maxn]={0};  // belong代表改点归并到第几个缩点
int n,suo_size=0,ans=maxn,fathur=0;

void dfs(int pos,int number){
int i;
vis[pos]=1;
belong[pos]=number;
for(i=0;i<vec[pos].size();i++){
if(vis[vec[pos][i]]==0&&color[vec[pos][i]]==color[pos]){
dfs(vec[pos][i],number);
}
}
}
void DFS(int pos){
int i;
vis[pos]=1;
for(i=0;i<vec[pos].size();i++){
if(vis[vec[pos][i]]==0&&color[vec[pos][i]]==color[pos]){
DFS(vec[pos][i]);
}
else if(vis[vec[pos][i]]==0&&color[vec[pos][i]]!=color[pos]){
change[belong[vec[pos][i]]].push_back(belong[pos]);
change[belong[pos]].push_back(belong[vec[pos][i]]);
}
}
}
void dps(int pos,int length){
int i,flag=1;
vis[pos]=1;
for(i=0;i<change[pos].size();i++){
if(vis[change[pos][i]]==0){
dps(change[pos][i],length+1);
flag=0;
}
}
if(flag==1){
if(ans<length){
ans=length;
fathur=pos;
}
}
return ;
}
int main(){
int i,j,l,r;
while(scanf("%d",&n)!=EOF){
for(i=1;i<=n;i++) scanf("%d",&color[i]);
for(i=1;i<=n-1;i++){
scanf("%d%d",&l,&r);
vec[l].push_back(r); vec[r].push_back(l);
}
memset(vis,0,sizeof(vis));  //其实大多ACM写成一次处理的,我喜欢加上EOF操作,所以vis要经常初始化,就慢了

for(suo_size=0,i=1;i<=n;i++){  //这次dfs将连通块儿缩到一个点
if(vis[i]==0){
suo_size++;
dfs(i,suo_size);
}
}

memset(vis,0,sizeof(vis));
for(i=1;i<=n;i++){              //这次DFS将缩点后树连接起来
if(vis[i]==0) DFS(i);
}
memset(vis,0,sizeof(vis));

ans=0; fathur=0;            //求树的直径
dps(1,0);
ans=0;                      //第一次的ans求出来没用。。。
memset(vis,0,sizeof(vis));  //记得初始化 访问数组
dps(fathur,0);

cout<<(ans+1)/2<<endl;      //结果先加1因为有奇偶情况,ans求的是两端最远距离,还要加上自己才是直径
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: