zoukankan      html  css  js  c++  java
  • 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 }
  • 相关阅读:
    Oracle 常用函数备查
    apt-get/dpkg常用指令备查
    vmware下虚拟机不能上网问题解决
    [转]JAVA并发编程学习笔记之Unsafe类
    solaris 下查看某程序所开端口
    java 守护线程
    Java实现非法访问异常
    Java使用ListIterator逆序ArrayList
    Java实现Map集合二级联动
    Java使用String类格式化当前日期
  • 原文地址:https://www.cnblogs.com/yuyanjiaB/p/10094958.html
Copyright © 2011-2022 走看看