噼里啪啦

我们学校的网线结构真神奇。有 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 }
原文地址:https://www.cnblogs.com/MyNameIsPc/p/7591639.html