• luogu P4149 [IOI2011] Race


    传送门

    点分治板子

    纪念一下1A

    就是之前的一个然后距离和深度换一下

    Code:

      1 #include<cstdio>
      2 #include<cstring>
      3 #include<algorithm>
      4 #define ms(a,b) memset(a,b,sizeof a)
      5 #define rep(i,a,n) for(int i = a;i <= n;i++)
      6 #define per(i,n,a) for(int i = n;i >= a;i--)
      7 #define inf 1e8
      8 using namespace std;
      9 typedef long long ll;
     10 #define B puts("GG")
     11 ll read() {
     12     ll as = 0,fu = 1;
     13     char c = getchar();
     14     while(c < '0' || c > '9') {
     15         if(c == '-') fu = -1;
     16         c = getchar();
     17     }
     18     while(c >= '0' && c <= '9') {
     19         as = as * 10 + c - '0';
     20         c = getchar();
     21     }
     22     return as * fu;
     23 }
     24 const int N = 200005;
     25 //head
     26 int n,k;
     27 int head[N],nxt[N<<1],mo[N<<1],cnt;
     28 int cst[N<<1];
     29 void _add(int x,int y,int w) {
     30     nxt[++cnt] = head[x];head[x] = cnt;
     31     mo[cnt] = y,cst[cnt] = w;
     32 }
     33 void add(int x,int y) {
     34     int w = read();
     35     _add(x,y,w),_add(y,x,w);
     36 }
     37 
     38 bool vis[N];
     39 int sze[N],mx[N],sum,rt;
     40 void getroot(int x,int f) {
     41     sze[x] = 1,mx[x] = 0;
     42     for(int i = head[x];i;i = nxt[i]) {
     43         int sn = mo[i];
     44         if(sn == f || vis[sn]) continue;
     45         getroot(sn,x);
     46         sze[x] += sze[sn];
     47         mx[x] = max(mx[x],sze[sn]);
     48     }
     49     mx[x] = max(mx[x],sum - sze[x]);
     50     if(mx[x] < mx[rt]) rt = x;
     51 }
     52 
     53 int tmp[1000005];
     54 int ans = inf;
     55 void getdis(int x,int f,int dis,int cnt) {
     56     if(dis > k) return;
     57     ans = min(ans,tmp[k - dis] + cnt);
     58     // minn[dis[x]] = min(minn[dis[x]],dep[x]);
     59     for(int i = head[x];i;i = nxt[i]) {
     60         int sn = mo[i];
     61         if(sn == f || vis[sn]) continue;
     62         getdis(sn,x,dis + cst[i],cnt + 1);
     63     }
     64 }
     65 
     66 void update(int x,int f,int dis,int cnt) {
     67     if(dis > k) return;
     68     tmp[dis] = min(tmp[dis],cnt);
     69     for(int i = head[x];i;i = nxt[i]) {
     70         int sn = mo[i];
     71         if(sn == f || vis[sn]) continue;
     72         update(sn,x,dis + cst[i],cnt + 1);
     73     }
     74 }
     75 
     76 void clear(int x,int f,int dis) {
     77     if(dis >= k) return;
     78     tmp[dis] = inf;
     79     for(int i = head[x];i;i = nxt[i]) {
     80         int sn = mo[i];
     81         if(sn == f || vis[sn]) continue;
     82         clear(sn,x,dis + cst[i]);
     83     }
     84 }
     85 
     86 void solve(int x) {
     87     tmp[0] = 0,vis[x] = 1;
     88     for(int i = head[x];i;i = nxt[i]) {
     89         int sn = mo[i];
     90         if(vis[sn]) continue;
     91         getdis(sn,x,cst[i],1),update(sn,x,cst[i],1);
     92     }
     93     clear(x,0,0);
     94     for(int i = head[x];i;i = nxt[i]) {
     95         int sn = mo[i];
     96         if(vis[sn]) continue;
     97         sum = sze[sn],mx[rt = 0] = inf;
     98         getroot(sn,sn),solve(rt);
     99     }
    100 }
    101 
    102 int main() {
    103     n = read(),k = read();
    104     rep(i,2,n) add(read()+1,read()+1);
    105     rep(i,1,k) tmp[i] = inf;
    106     sum = n,mx[rt = 0] = inf;
    107     getroot(1,1),solve(rt);
    108     printf("%d
    ",ans >= inf ? -1 : ans);
    109     return 0;
    110 }
  • 相关阅读:
    用户空间与内核空间,进程上下文与中断上下文[总结]【转】
    select、poll、epoll之间的区别总结[整理]【转】
    v4l2驱动文档之——streaming IO【转】
    Linux网络编程一步一步学【转】
    V4L2驱动的移植与应用(二+三)【转】
    【PHP面向对象(OOP)编程入门教程】20.PHP5接口技术(interface)
    【PHP面向对象(OOP)编程入门教程】19.抽象方法和抽象类(abstract)
    【PHP面向对象(OOP)编程入门教程】18.__call()处理调用错误
    【PHP面向对象(OOP)编程入门教程】17.克隆对象__clone()方法
    【PHP面向对象(OOP)编程入门教程】16.__toString()方法
  • 原文地址:https://www.cnblogs.com/yuyanjiaB/p/10094958.html
Copyright © 2020-2023  润新知