• hdu5016


    题意:给定一个n个点的图,这个图是一棵树,然后有些点建立了集市。并且没有集市的地方去集市一定是去最近的,如果距离相同,那么则去标号最小的。。现在你还能在建一个集市,问建完这个集市最多有多少个点来这里。。

    思路:

         现对于每个点求该点到有标记点最近的距离,记录距离及其最近标号,可以用树形dp或者spfa搞。。

         然后我们任意选定一个点建树,建完后进行点分治。。

        对于当前分治快的跟rt,求rt到每个点的距离为dis,near为到标记点最近的距离

        那么对于不同子树的点u,v,如果dis[u] + dis[v] < near[v],那么如果u建立集市v肯定到u。。

        那么我们把式子变形下,dis[u] < near[v] - dis[v],对于u直接二分查找统计即可。。

        我们可以先不管哪棵子树先统计一边,然后再减去相同的即可,这样写起来方便点。。写起来还蛮像poj1741的。。

    code:

      1 /*
      2  * Author:  Yzcstc
      3  * Created Time:  2014/10/2 17:37:34
      4  * File Name: hdu5016.cpp
      5  */
      6 #pragma comment(linker, "/STACK:102400000,102400000")
      7 #include<cstdio>
      8 #include<iostream>
      9 #include<cstring>
     10 #include<cstdlib>
     11 #include<cmath>
     12 #include<algorithm>
     13 #include<string>
     14 #include<map>
     15 #include<set>
     16 #include<vector>
     17 #include<queue>
     18 #include<stack>
     19 #include<ctime>
     20 #define repf(i, a, b) for (int i = (a); i <= (b); ++i)
     21 #define repd(i, a, b) for (int i = (a); i >= (b); --i)
     22 #define M0(x)  memset(x, 0, sizeof(x))
     23 #define clr(x, y) memset(x, y, sizeof(x))
     24 #define N 120000
     25 #define Inf 0x3fffffff
     26 #define x first
     27 #define y second
     28 using namespace std;
     29 typedef pair<int, int> pii;
     30 struct edge{
     31      int v, w, next;
     32      edge(){}
     33      edge(int _v, int _w, int _next):v(_v), w(_w), next(_next){}
     34 } e[N<<1];
     35 int last[N], n, len, have[N], ans[N];
     36 int inq[N];
     37 pii ner[N];
     38 
     39 void add(int u, int v, int w){
     40     e[len] = edge(v, w, last[u]), last[u] = len++;   
     41 }
     42 
     43 void init(){
     44      clr(last, -1);
     45      len = 0;
     46      int u, v, w;
     47      for (int i = 1; i < n; ++i){
     48           scanf("%d%d%d", &u, &v, &w);
     49           add(u, v, w), add(v, u, w);
     50      }
     51      repf(i, 1, n) scanf("%d", &have[i]);
     52 }
     53 
     54 void gao(){
     55      repf(i, 0, n) ner[i].x = ner[i].y = Inf, inq[i] = 0;
     56      queue<int> q;
     57      repf(i, 1, n) if (have[i]){
     58            ner[i].x = 0, ner[i].y = i;
     59            q.push(i), inq[i] = 1;
     60      }
     61      int u, v;
     62      pii tmp;
     63      while (!q.empty()){
     64            u = q.front();
     65            q.pop(), inq[u] = 0;
     66            for (int p = last[u]; ~p; p = e[p].next){
     67                  v = e[p].v;
     68                  tmp.x = ner[u].x + e[p].w, tmp.y = ner[u].y;
     69                  if (tmp < ner[v]){
     70                         ner[v] = tmp;
     71                         if (!inq[v]) inq[v] = 1, q.push(v); 
     72                  }
     73            }
     74      }
     75      
     76 }
     77 /*** 点分治-begin **/
     78 int vis[N], sz, msize[N], f[N], size[N], belong[N], ss, ff[N];
     79 int dis[N];
     80 pair<int, int> s[N], tp;
     81 
     82 void dfs(int u, int fa){ //calculate the size
     83      f[sz++] = u;
     84      msize[u] = 0, size[u] = 1;
     85      int v;
     86      for (int p = last[u]; ~p; p = e[p].next){
     87           v = e[p].v;
     88           if (v == fa || vis[v]) continue;
     89           dfs(v, u);
     90           size[u] += size[v];
     91           msize[u] = max(size[v], msize[u]);
     92      } 
     93 }
     94 
     95 void dfs(int u, int fa, int dist){
     96      dis[u] = dist, ff[ss++] = u;
     97      int v;
     98      for (int p = last[u]; ~p; p = e[p].next){
     99           v = e[p].v;
    100           if (v == fa || vis[v]) continue;
    101           dfs(v, u, dist + e[p].w);
    102      } 
    103 }
    104 
    105 void calculate(int u, int dist){
    106      ss = 0;
    107      dfs(u, 0, dist);
    108      for (int i = 0; i < ss; ++i)
    109           s[i].x = ner[ff[i]].x - dis[ff[i]], s[i].y = ner[ff[i]].y;
    110      sort(s, s+ss);
    111      int t;
    112      for (int i = 0; i < ss; ++i) if (!have[ff[i]]){
    113           tp.x = dis[ff[i]], tp.y = ff[i];
    114           t = lower_bound(s, s+ss, tp) - s;
    115           ans[ff[i]] += (dist > 0) ? (t - ss) : (ss - t); 
    116      }          
    117 }
    118 
    119 void dfs(int u){
    120      sz = 0;
    121      dfs(u, 0);
    122      int rt = 0, tmp, v;
    123      for (int i = 0; i < sz; ++i){
    124            tmp = max(msize[f[i]], sz-1-size[f[i]]);
    125            if (tmp <= (sz>>1)) { rt = f[i]; break; }
    126      }
    127      calculate(rt, 0);
    128      vis[rt] = 1;
    129      for (int p = last[rt]; ~p; p = e[p].next){
    130            v = e[p].v;
    131            if (vis[v]) continue;
    132            calculate(v, e[p].w);
    133            dfs(v);
    134      }
    135 }
    136 /**** 点分治-end***/
    137 
    138 void solve(){
    139      gao();
    140      M0(vis);
    141      M0(ans);
    142      dfs(1);
    143      int mx = 0;
    144      for (int i = 1; i <= n; ++i)
    145            mx = max(ans[i], mx);
    146      printf("%d
    ", mx); 
    147 }
    148 
    149 int main(){
    150 //    freopen("a.in", "r", stdin);
    151 //    freopen("a.out", "w", stdout);
    152     while (scanf("%d", &n) != EOF){
    153           init();
    154           solve();
    155     }
    156     return 0;
    157 }
    View Code
  • 相关阅读:
    重构DataGridView的方法
    Js中得到radiobuttonlist 和CheckBoxList 的值
    01、Android系统系统架构
    10、JavaEEDBUtils工具类
    07、JavaEEJSP自定义标签
    11、JavaEEFilter
    08、JavaEEMysql基础
    09、JavaEEJDBC
    简单易忘哈哈(sql语句中的空格问题)
    定义Connection对象con的好处
  • 原文地址:https://www.cnblogs.com/yzcstc/p/4004457.html
Copyright © 2020-2023  润新知