您的位置:首页 > 其它

hdu 4868 树分治

2015-07-05 11:02 381 查看
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<map>
#include<iostream>
#include<queue>
using namespace std;

const int M = 60005;
struct Edge{
int v, next, w;
}edge[M << 2], ee[M ];
map<int, int> mp;
int E, head[M], hh[M], EE;
int root, mmax;
int cc[M], dd[M];
int cnt[M], mx[M], sz[M];
int wh[M], dep[M], dis[M];
int n, m, k;
int vis[M];

void init(){
memset(head, -1, sizeof(head));
memset(hh, -1, sizeof(hh));
memset(cnt, 0, sizeof(cnt));
E = EE = 0;
}

void add_edge(int s, int v, int w){
edge[E].v = v;
edge[E].w = w;
edge[E].next = head[s];
head[s] = E ++;
}

void add(int s, int v, int w){
ee[EE].v = v;
ee[EE].next = hh[s];
ee[EE].w = w;
hh[s] = EE ++;
}

const int inf = 0x3f3f3f3f;
int mm ;

void Dijk(){
priority_queue<pair<int, int> > q;
for(int i = 0; i < n; i ++){dis[i] = inf;}
dis[0] = 0;
memset(vis, 0, sizeof(vis));
q.push(make_pair(0, 0));
while(!q.empty()){
pair<int, int> now = q.top(); q.pop();
int u = -now.second; int dd = -now.first;
if(vis[u] == 1) continue;
vis[u] = 1;
for(int i = head[u]; i != -1; i = edge[i].next){
int v = edge[i].v;
if(dis[v] > dis[u] + edge[i].w){
dis[v] = dis[u] + edge[i].w;
wh[v] = u;
q.push(make_pair(-dis[v], -v));
}
}
}
for(int i = 1; i < n; i ++) {
add(wh[i], i, - dis[wh[i]] + dis[i]);
add(i, wh[i], - dis[wh[i]] + dis[i]);
}
}

void dfs1(int u, int fa){
sz[u] = 1; mx[u] = 0;
for(int i = hh[u]; i != -1; i = ee[i].next){
int v = ee[i].v;
if(v != fa && vis[v] == 0){
dfs1(v, u);
mx[u] = max(mx[u], sz[v]);
sz[u] += sz[v];
}
}
}

void dfs2(int u, int fa, int rt){
mx[u] = max(mx[u], sz[rt] - sz[u]); if(mx[u] < mmax){
mmax = mx[u]; root = u;
}
for(int i = hh[u]; i != -1; i = ee[i].next){
int v = ee[i].v;
if(v != fa && vis[v] == 0){
dfs2(v, u, rt);
}
}
}

void dfs(int u, int fa, int step, int stop, int w){
if(w > cc[step]) {
cc[step] = w;
dd[step] = 1;
}else if(w == cc[step]) dd[step] ++;
if(step == stop) return ;
for(int i = hh[u]; i != -1; i = ee[i].next){
int v = ee[i].v;
if(v == fa || vis[v]) continue;
dfs(v, u, step+1, stop, w + ee[i].w);
}
}

int cal(int u, int tn, int w){
//printf("%d %d %d\n", u, sum, w);
for(int i = 0; i <= tn+1; i ++) {cc[i] = 0; dd[i] = 0;}
//memset(cnt, 0, sizeof(cnt));
dfs(u, -1, 1, tn, w);
int ans = 0;
if(cc[k-1]) {
mm = max(mm, cc[k-1]);
mp[cc[k-1]] += dd[k-1];
}
//printf("u = %d\n", u);
//for(int i = 1; i <= tn+1; i ++) printf("%d %d %d, %d\n", cc[i], dd[i], cnt[i], dep[i]);
for(int i = 1; i < k; i ++){
if(  cc[i] == 0) break;
mp[cc[i] + cnt[k - 1 - i]] += dd[i] * dep[k-1-i];
mm = max(mm, cc[i] + cnt[k-1-i]);
}
return ans;
}

void update(int tn){
for(int i = 1; i <= tn; i ++){
if(cc[i]) {
if(cnt[i] == cc[i]) dep[i] += dd[i];
else if(cnt[i] < cc[i]) {
cnt[i] = cc[i]; dep[i] = dd[i];
}
}
else break;
}
}

int ans;
void solve(int u){
mmax = M;
root = u;
dfs1(u, -1);
dfs2(u, -1, u);
vis[root] = 1;
for(int i = 0; i <= mx[root]+1; i ++) {cnt[i] = 0; dep[i] = 0;}
for(int i = hh[root]; i != -1; i = ee[i].next){
int v = ee[i].v;
if(vis[v]) continue;
int tmp = cal(v, min(k-1, mx[v] + 1), ee[i].w);
update(min(k-1, mx[v] + 1));
}
for(int i = hh[root]; i != -1; i = ee[i].next){
int v = ee[i].v;
if(vis[v] == 0)
solve(v);
}
}

/*
int pah(int u, int fa, int step){
int m1, m2;
m1 = 0; m2 = 0;
for(int i = hh[u]; i != -1; i = ee[i].next){
int v = ee[i].v;
if(v == fa) continue;
int tmp = pah(v, u, step+1) + ee[i].w;
if(tmp > m1){
m2 = m1; m1 = tmp;
}else if(tmp > m2) m2 = tmp;
}
int ret = m1;
if(step > m1){
m2 = m1; m1 = step;
}else if(step > m2) m2 = step;
mm = max(mm, m1+m2+1);
return ret;
}
*/
int read(){
int ans = 0;
char g;
while((g = getchar()) == ' ' || g == '\n') ;
ans = g - '0';
while((g = getchar()) != ' ' && g != '\n') ans = ans * 10 + g - '0';
return ans;
}
int main(){
int T;
//freopen("1011.in", "r", stdin);
scanf("%d", &T);
//T = read();
while(T --){
//      n = read(); m = read(); k = read();
scanf("%d%d%d", &n, &m, &k);
int a, b, c;
init();
for(int i = 0; i < m; i ++){
//            a = read(); b = read(); c = read();
scanf("%d%d%d", &a, &b, &c);
a --; b --;
add_edge(a, b, c);
add_edge(b, a, c);
}
Dijk();
memset(vis, 0, sizeof(vis));
mm = 0;
solve(1);
printf("%d %d\n", mm, mp[mm]);
}
return 0;
}


  
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: