码迷,mamicode.com
首页 > 其他好文 > 详细

2015.10.15 --- 2014 牡丹江

时间:2015-10-31 00:20:00      阅读:233      评论:0      收藏:0      [点我收藏+]

标签:

练了好久的了

过了4题

现在才补

真是懒成dog了---

A

签到

B

练的时候虽然讨论出了正确的做法,,可是当时根本不觉得是对的- -

做法是,求三次树的直径

第一次,求出整棵树的直径,找到直径的中点,将整棵树分成两颗子树

第二次,求出第一棵子树的直径的中点

第三次,求出第二棵子树的直径的中点

-------写了好几天----最后还是看了题解的写法---

自己写的又wa又T的-----好----搓----啊----

有两个地方自己写的时候没有搞太清楚,

先是将整棵子树分成两半的时候,不知道从哪里断开

然后就是找中点的时候,不知道找直径是奇数,偶数的时候该怎么处理,,,

总之,,,就是,,,-----sad------

技术分享
#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
#include<vector>
#include<queue>
using namespace std;

//wei  ziji +u >_< 

const int INF = (1<<30)-1;
const int maxn = 5e5+5;
int n;
int d[maxn],vis[maxn],p[maxn],p1[maxn],p2[maxn];
vector<int>g[maxn];
int st,ed;//ed  记录下找到的直径的 端点
int rr;//直径 

void bfs(int s){
    queue<int> q;
    p[s] = 0;d[s] = 1;
    rr = 1;
    ed = s;
    q.push(s);
    while(!q.empty()){
        int u = q.front();q.pop();
        for(int i = 0;i < g[u].size();i++){
            int v = g[u][i];
            if(vis[v]) continue;
            if(v == p[u]) continue;
            d[v] = d[u]+1;
            p[v] = u;
            q.push(v);
            if(d[v] > rr){
                rr = d[v];
                ed = v;
            }
        }
    }
}

void solve(){
    //整棵树的直径
    memset(vis,0,sizeof(vis));
    bfs(1);
    bfs(ed);
//    for(int i = 1;i <= n;i++) printf("p[%d] = %d\n",i,p[i]);
//    printf("rr = %d  ed = %d\n",rr,ed);
//    for(int i = 1;i <= n;i++) printf("d[%d] = %d\n",i,d[i]);
    //找将这棵树断开的点,也就是这棵树直径的中点
    int mid = ed;
    int x = d[ed];
    while(x != rr/2 +1){
        mid =p[mid];
        x = d[mid];
    //    printf("---x = %d\n",x);
    }
//    printf("mid = %d\n",mid);
    int res = 0,c1,c2;
    
    // 第一颗子树的
    vis[mid] = 1; 
    bfs(p[mid]);
    st = ed;
    bfs(ed);
    c1 = ed;x = d[ed];
    while(x != rr/2+1){
        c1 = p[c1];
        x = d[c1];
    } 
    res = max(res,rr/2);
    
    //第二棵子树的
    vis[mid] = 0;
    vis[p[mid]] = 1;
    bfs(mid);
    st = ed;
    bfs(ed);
    c2 = ed;x = d[ed];
    while(x!=rr/2+1){
        c2 = p[c2];
        x = d[c2]; 
    } 
    res = max(res,rr/2);
    printf("%d %d %d\n",res,c1,c2);
} 


int main(){
    int T;
    scanf("%d",&T);
    while(T--){
        scanf("%d",&n);
        for(int i = 1;i <= n;i++) g[i].clear();
        for(int i=1;i < n;i++){
            int u,v;
            scanf("%d %d",&u,&v);
            g[u].push_back(v);
            g[v].push_back(u);
        }
        solve();
    }
    return 0; 
}
View Code

 

C

 

D

dp,,他们做的

 

E

 

F

 

G

 

H

 

I

套公式,注意0的时候

 

J

 

K

贪心

 

2015.10.15 --- 2014 牡丹江

标签:

原文地址:http://www.cnblogs.com/wuyuewoniu/p/4924650.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!