luogu P2680 运输计划

开始T啊,T啊,T啊
以为写的常数大,然后就在卡常
死活卡不过去啊QAQQQQQQ
然后发现自己的复杂度多乘了个logn啊啊啊啊啊
其实吧每组的lca预处理处来就好了啊啊啊啊啊

代码

#include<cstdio> 
#include<cstring> 
#include<algorithm> 
const int maxn = 400007;
inline int read() {
    int x = 0,f = 1;
    char c = getchar(); 
    while(c < '0' || c > '9'){if(c == '-')f = -1;c = getchar();} 
    while(c <= '9' && c >= '0')x = x * 10 + c - '0',c = getchar(); 
    return x * f;
} 
int l,r;
struct Node {
    int v,w,next;
}edge[maxn << 1]; 
int Lca[maxn]; 
int head[maxn],num = 0; 
inline void add_edge(int u,int v,int w) {  
    edge[++ num].v = v;edge[num].w = w,edge[num].next = head[u];head[u] = num;  
} 
int n,m;int dis[maxn],deep[maxn],fa[maxn][22];   
void dfs(int x,int f) {  
    deep[x] = deep[f] + 1;fa[x][0] = f;  
    for(int i = 0;fa[x][i];++ i) { 
        fa[x][i + 1] = fa[fa[x][i]][i];  
    } 
    for(int i = head[x];i;i = edge[i].next) { 
        int v = edge[i].v; 
        if(v == f)continue; 
        dis[v] = dis[x] + edge[i].w;  
        dfs(v,x); 	 
    }  
} 
int lca(int x,int y) { 
    if(deep[x] > deep[y]) std::swap(x,y); 
    for(int i = 18;i >= 0;-- i) 
        if(deep[x] <= deep[fa[y][i]] ) y = fa[y][i]; 
    if(x == y) return x;  
    for(int i = 18;i >= 0;-- i)  
        if(fa[x][i] != fa[y][i]) x = fa[x][i],y = fa[y][i];  
    return fa[x][0]; 
}
int U[maxn],V[maxn];  
inline int Dis(int i) { 
    return dis[U[i]] + dis[V[i]] - 2 * dis[Lca[i]]; 
} 
int hav[maxn],H[maxn];  
int tmp_max,numm = 0,qoq;  
bool flag = false; 
void Dfs(int x,int f) { 
    if(flag == true) return;
    for(int i = head[x];i;i = edge[i].next) { 
        int v = edge[i].v; 
        if(v == f) continue;  
        Dfs(v,x); 
        if(hav[v] == numm) {
            if(tmp_max - edge[i].w <= qoq ) {
                flag = true;return;
            }
        }
        hav[x] += hav[v]; 
    } 
}
bool check(int x) {
    flag = false; qoq = x;
    for(int i = 1;i <= n;++ i) hav[i] = 0;  
    tmp_max = 0,numm = 0; 
    for(int i = 1;i <= m;++ i) { 
        int d = Dis(i); 
        if(d > x) {
        numm ++;
          	tmp_max = std::max(tmp_max,d);	
          	hav[U[i]]++,hav[V[i]] ++; 
          	hav[Lca[i]] -= 2;   
        }
    }
    //printf("%d\n",lca(2,5)); 
    if(!num) return true; 
    Dfs(1,0); 
    return flag; 
}
int main() { 
    n = read(),m = read();
    for(int a,b,c,i = 1;i < n;++ i) { 
        a = read(),b = read(),c = read() ;
        add_edge(a,b,c);add_edge(b,a,c); 
    } 
    dfs(1,0); 
    for(int i = 1;i <= m;++ i) 
 		U[i] = read(),V[i] = read(); 
    for(int i = 1;i <= m;++ i) 
    		Lca[i] = lca(U[i],V[i]),r = std::max(r,Dis(i)); 
    int ans = 0 ;
    while(l <= r) {
        int mid = l + r >> 1;
        if(check(mid)) ans = mid,r = mid - 1;
        else l = mid + 1;
    }	
    printf("%d\n",ans); 
    return 0; 
} 



posted @ 2018-05-11 06:53  zzzzx  阅读(145)  评论(0编辑  收藏  举报