zoukankan      html  css  js  c++  java
  • Noip2015Day2T3 运输计划

    题目链接

    problem

    一棵n个点带边权的树,有m个条路径。选择一条边,将其权值变为0,使得长度最长的路径长度最小。求该长度最小为多少。

    solution

    其实仔细一想并不难。

    删除一条边会导致所有经过这条边的路径长度减少该边长度。所有没经过这条边的路径长度不变。

    所以我们只需要知道没经过该边的路径中的长度最大值,以及经过该边的路径中长度最大值。

    显然经过该边的路径长度最大值我们可以当做最长路径的最大值。

    现在只要对于每条边都能够计算出没经过该边的路径长度最大值即可。

    我们发现并不需要对于每条边都求出该值。

    因为删除的边肯定位于最长路径上。

    然后我们就把最长路径扯平。并对上面的边进行编号。

    如图,对于(S-T)这条路径,会在删除(1,4,5)这三条边时产生贡献。所以我们只要用两个数组分别记录出前缀最大值和后缀最大值即可。

    然后枚举删除的边,记录最优答案。

    code

    #include<cstdio>
    #include<iostream>
    #include<cstring>
    #include<queue>
    #include<vector>
    #include<ctime>
    #include<algorithm>
    using namespace std;
    typedef long long ll;
    const int N = 300100,logN = 20;
    ll read() {
    	ll x = 0,f = 1;char c = getchar();
    	while(c < '0' || c > '9') {
    		if(c == '-') f = -1;
    		c = getchar();
    	}
    	while(c >= '0' && c <= '9') {
    		x = x * 10 + c - '0';
    		c = getchar();
    	}
    	return x * f;
    }
    struct node {
    	int u,v,nxt,w,bz;
    }e[N << 1];
    int head[N],ejs;
    void add(int u,int v,int w) {
    	e[++ejs].v = v;e[ejs].u = u;e[ejs].nxt = head[u];head[u] = ejs;e[ejs].w = w;
    }
    
    int id[N],cnt,dis[N];
    
    int DFS(int u,int V,int fa) {
    	if(u == V) {
    		id[u] = ++cnt;return 1;
    	}
    	for(int i = head[u];i;i = e[i].nxt) {
    		int v = e[i].v;
    		if(v == fa) continue;
    		if(DFS(v,V,u)) {
    			id[u] = ++cnt;
    			e[i].bz = 1;
    			return 1;
    		}
    	}
    	return 0;
    }
    void mark(int u,int p) {
    	id[u] = p;
    	for(int i = head[u];i;i = e[i].nxt) {
    		int v = e[i].v;
    		if(id[v]) continue;
    		mark(v,p);
    	}
    }
    int lca[N][21],dep[N];
    void get_lca(int u,int fa) {
    	dep[u] = dep[fa] + 1;
    	
    	for(int i = 1;i <= logN;++i) lca[u][i] = lca[lca[u][i - 1]][i - 1];
    	
    	for(int i = head[u];i;i = e[i].nxt) {
    		int v = e[i].v;
    		if(v == fa) continue;
    		dis[v] = dis[u] + e[i].w;
    		lca[v][0] = u;
    		get_lca(v,u);
    	}
    	
    }
    int LCA(int x,int y) {
    	if(dep[x] < dep[y]) swap(x,y);
    	
    	for(int i = logN;i >= 0;--i)
    		if(dep[lca[x][i]] >= dep[y]) x = lca[x][i];
    
    	for(int i = logN;i >= 0;--i)
    		if(lca[x][i] != lca[y][i]) x = lca[x][i],y = lca[y][i];
    	
    	if(x != y) return lca[x][0];
    	return x;
    	
    }
    int mx1[N],mx2[N];
    struct QUE {
    	int s,t,len;
    }Q[N];
    int main() {
    	int mxx = 0;
    	int n = read(),m = read();
    	
    	for(int i = 1;i < n;++i) {
    		int u = read(),v = read(),w = read();
    		add(u,v,w);add(v,u,w);
    	}
    
    	get_lca(1,0);
    	
    	int S = 0,T = 0;
    
    	for(int i = 1;i <= m;++i) {
    		Q[i].s = read();Q[i].t = read();
    		Q[i].len = dis[Q[i].s] + dis[Q[i].t] - dis[LCA(Q[i].s,Q[i].t)] * 2;
    		if(Q[i].len > mxx) {
    			mxx = Q[i].len;
    			S = Q[i].s;T = Q[i].t;
    		}
    	}
    
    	DFS(S,T,0);
    	
    	for(int i = 1;i <= n;++i) {
    		if(id[i]) {
    			mark(i,id[i]);
    		}
    	}
    	
    	for(int i = 1;i <= m;++i) {
    		int s = Q[i].s,t = Q[i].t;
    		
    		int l = id[s],r = id[t];
    		if(l > r) swap(l,r);
    		
    		mx1[l - 1] = max(mx1[l - 1],Q[i].len);
    		mx2[r] = max(mx2[r],Q[i].len);
    	}
    	
    	for(int i = cnt;i >= 0;--i) {
    		mx1[i] = max(mx1[i],mx1[i + 1]);
    	}
    	for(int i = 1;i <= cnt;++i)
    		mx2[i] = max(mx2[i],mx2[i - 1]);
    	
    	int ans = 1e9;
    	
    	for(int i = 1;i <= ejs;++i) {
    		if(e[i].bz) {
    			int l = id[e[i].u],r = id[e[i].v];
    			if(l > r) swap(l,r);
    			
    			int k = max(max(mx1[l],mx2[l]),mxx - e[i].w);
    			
    			ans = min(ans,k);
    		}
    	}
    	
    	cout<<(ans == 1e9 ? 0 : ans);
    	
    	return 0;
    }
    
  • 相关阅读:
    【学习笔记】斯特林数(未完成)
    【题解/学习笔记】点分树
    【题解】[国家集训队] Crash 的文明世界
    【题解】SP34096 DIVCNTK
    【题解】Loj6053 简单的函数
    【题解】[ZJOI2012]网络
    【题解】bzoj3252 攻略
    【题解】[POI2014]HOT-Hotels 加强版
    IDEA文件夹变红,轻松删除SVN版本控制关联
    配置dataguard broker并主从切换
  • 原文地址:https://www.cnblogs.com/wxyww/p/noip2015Day2T3.html
Copyright © 2011-2022 走看看