zoukankan      html  css  js  c++  java
  • 噼里啪啦

    我们学校的网线结构真神奇。有 n 台服务器编号 1~n,一些服务器直接连接IP 为 0 的网关,所有 n 台服务器网线相互连接。宁波来台风了!噼里啪啦~
    一阵雷雨过后,我们发现很多服务器都无法访问了,为了评估破坏情况,我们觉得打开一些服务器随机 ping 其他服务器,然后记录不成功的情况。现在他需要一个程序分析记录,最少有几台服务器遭到雷电破坏。

      贪心,先求一遍lca,然后根据lca的深度排序lca,从深往浅搜,然后如果用一个lca,那就把lca所在的子树都打上标记。如果后面求lca的时候,发现标记,就不把它计入ans。

      1 #include <cstdio>
      2 #include <cstring>
      3 #include <algorithm>
      4 using namespace std;
      5 const int maxn=1e5+5, maxq=5e5+5;
      6 
      7 inline int max(int x, int y){ return x<y?y:x; }
      8 
      9 struct lca{
     10     int data, a, b, dep;
     11 }q[maxq];
     12 bool operator <(const lca &x, const lca &y){
     13     return x.dep>y.dep;
     14 }
     15 
     16 class Graph{
     17 public:
     18     struct Edge{
     19         Graph *belong; int to, next;
     20         Edge& operator ++(){ *this=belong->edge[next]; return *this; }
     21         int operator *(){ return to; }
     22     };
     23     void reset(){
     24         edge[0].to=-1;
     25         memset(fir, 0, sizeof(fir));
     26         cntedge=0;
     27     }
     28     void addedge(int x, int y){
     29         Edge &e=edge[++cntedge];
     30         e.belong=this, e.to=y;
     31         e.next=fir[x], fir[x]=cntedge;
     32     }
     33     Edge get_link(int x){ return edge[fir[x]]; }
     34 private:
     35     int cntedge, fir[maxn];
     36     Edge edge[maxn];
     37 };
     38 
     39 int n, m, dep[maxn], son[maxn], size[maxn], fa[maxn];
     40 int times, top[maxn], dfn[maxn], cnt, L, R;
     41 int seg[maxn*4], mark[maxn*4];
     42 Graph g;
     43 
     44 void dfs1(int now, int par){
     45     int nc, maxsize=0;
     46     for (Graph::Edge e=g.get_link(now); ~*e; ++e){
     47         nc=*e;
     48         if (nc==par) continue;
     49         fa[nc]=now;
     50         dep[nc]=dep[now]+1;
     51         dfs1(nc, now);
     52         size[now]+=size[nc];
     53         if (size[nc]>maxsize){
     54             maxsize=size[nc];
     55             son[now]=nc;
     56         }
     57     }
     58     ++size[now];
     59 }
     60 
     61 void dfs2(int now, int par){
     62     int nc;
     63     dfn[now]=++times;
     64     if (son[now]){ //初始化!
     65         top[son[now]]=top[now];
     66         dfs2(son[now], now);
     67     }
     68     for (Graph::Edge e=g.get_link(now); ~*e; ++e){
     69         nc=*e;
     70         if (nc==par||nc==son[now]) continue;
     71         top[nc]=nc;
     72         dfs2(nc, now);
     73     }
     74 }
     75 
     76 int prelca(int x, int y){
     77     while (top[x]!=top[y]){
     78         //这里要比较top谁高谁低!
     79         if (dep[top[x]]>dep[top[y]]) x=fa[top[x]];
     80         else y=fa[top[y]];
     81     }
     82     //这里是小于!!!
     83     return dep[x]<dep[y]?x:y;
     84 }
     85 
     86 int query(int now, int l, int r){
     87     if (l>=L&&r<=R) return seg[now];
     88     if (mark[now]){
     89         seg[now<<1]=seg[now<<1|1]=seg[now];
     90         mark[now<<1]=mark[now<<1|1]=seg[now]; mark[now]=0;
     91     }
     92     int mid=(l+r)>>1, flag=0;
     93     if (mid>=L) flag=max(query(now<<1, l, mid), flag);
     94     if (mid<R) flag=max(query(now<<1|1, mid+1, r), flag);
     95     return flag>0?1:0;
     96 }
     97 
     98 void modify(int now, int l, int r){
     99     if (l>=L&&r<=R){ seg[now]=1; mark[now]=1; return; }
    100     if (mark[now]){
    101         seg[now<<1]=seg[now<<1|1]=seg[now];
    102         mark[now<<1]=mark[now<<1|1]=seg[now];
    103     }
    104     int mid=(l+r)>>1;
    105     if (mid>=L) modify(now<<1, l, mid);
    106     if (mid<R) modify(now<<1|1, mid+1, r);
    107     if (seg[now<<1]+seg[now<<1|1]) seg[now]=1;
    108 }
    109 
    110 int lalca(int x, int y){
    111     while (top[x]!=top[y]){
    112         if (dep[top[x]]>dep[top[y]]){
    113             L=dfn[top[x]], R=dfn[x];
    114             if (query(1, 1, n+1)>0) return -1;
    115             x=fa[top[x]];
    116         }
    117         else {
    118             L=dfn[top[y]], R=dfn[y];
    119             if (query(1, 1, n+1)>0) return -1;
    120             y=fa[top[y]];
    121         }
    122     }
    123     //最后也有可能断掉!
    124     if (dep[x]>dep[y]){
    125         L=dfn[y], R=dfn[x];
    126         if (query(1, 1, n+1)>0) return -1;
    127     } else {
    128         L=dfn[x], R=dfn[y];
    129         if (query(1, 1, n+1)>0) return -1;
    130     }
    131     return dep[x]<dep[y]?x:y;
    132 }
    133 
    134 void init(){
    135     g.reset();
    136     times=0, cnt=0;
    137     memset(size, 0, sizeof(size));
    138     memset(seg, 0, sizeof(seg));
    139     memset(mark, 0, sizeof(mark));
    140     memset(son, 0, sizeof(son));
    141 }
    142 
    143 int main(){
    144     int t;
    145     scanf("%d", &t);
    146     int x, y;
    147     for (int tt=0; tt<t; ++tt){
    148         init();
    149         scanf("%d", &n);
    150         for (int i=0; i<n; ++i){
    151             scanf("%d%d", &x, &y);
    152             g.addedge(x, y);
    153             g.addedge(y, x);
    154         }
    155         dfs1(0, -1);
    156         dfs2(0, -1);
    157         scanf("%d", &m);
    158         for (int i=0; i<m; ++i){
    159             scanf("%d%d", &x, &y);
    160             q[i].a=x;
    161             q[i].b=y;
    162             q[i].dep=dep[prelca(x, y)];
    163         }
    164         sort(q, q+m);
    165         int result, ans=0;
    166         for (int i=0; i<m; ++i){
    167             result=lalca(q[i].a, q[i].b);
    168             if (!~result) continue;
    169             else {
    170                 L=dfn[result], R=dfn[result]+size[result]-1;
    171                 modify(1, 1, n+1);
    172                 ++ans;
    173             }
    174         }
    175         printf("Case #%d: %d
    ", tt+1, ans);
    176     }
    177     return 0;
    178 }
  • 相关阅读:
    vscode中执行gulp task的简便方法
    5G即将到来,你还会购买4G手机吗?
    小屏幕手机汇总
    NoSQL数据库的分布式算法详解
    如何在网页界面设计中正确的留出空白空间?
    iconfont的三种使用方式
    MySQL修改密码方法汇总
    Docker镜像与容器
    微观经济学
    经营的原点 书评
  • 原文地址:https://www.cnblogs.com/MyNameIsPc/p/7591639.html
Copyright © 2011-2022 走看看