hdu 6203 ping ping ping(贪心+树状数组+dfs序)
题意:
给你一棵n+1个节点树,现在有q条路径不通,问你最少有多少个节点坏掉了。
题解:
考虑贪心,对这q条路径求一下lca,按照lca的深度从大到小排序。
然后for每条路径,看看x或者y是否在已经被禁止的子树里面,如果都不在,那么ans++,将lca(x,y)这棵子树标记为禁止。
1 #include<bits/stdc++.h> 2 #define F(i,a,b) for(int i=(a);i<=(b);++i) 3 #define mst(a,b) memset(a,b,sizeof(a)) 4 using namespace std; 5 6 const int N=1e4+7; 7 int t,n,m,sum[N]; 8 int nxt[2*N],g[N],v[2*N],ed,x,y; 9 int hs[N],fa[N],top[N],dep[N],sz[N],dfsl[N],dfsr[N],idx; 10 11 void adg(int x,int y){v[++ed]=y,nxt[ed]=g[x],g[x]=ed;} 12 13 void dfs1(int u,int pre){ 14 dfsl[u]=++idx,dep[u]=dep[pre]+1,hs[u]=0,fa[u]=pre,sz[u]=1; 15 for(int i=g[u];i;i=nxt[i])if(v[i]!=pre) 16 dfs1(v[i],u),sz[u]+=sz[v[i]],hs[u]=(sz[v[i]]>sz[hs[u]])?v[i]:hs[u]; 17 dfsr[u]=idx; 18 } 19 void dfs2(int u,int tp){ 20 top[u]=tp; 21 if(hs[u])dfs2(hs[u],tp); 22 for(int i=g[u];i;i=nxt[i]) 23 if(v[i]!=fa[u]&&v[i]!=hs[u])dfs2(v[i],v[i]); 24 } 25 26 int LCA(int x,int y) 27 { 28 while(top[x]!=top[y]) 29 dep[top[x]]>dep[top[y]]?x=fa[top[x]]:y=fa[top[y]]; 30 return dep[x]<dep[y]?x:y; 31 } 32 33 inline void add(int x,int c){while(x<=n)sum[x]+=c,x+=x&-x;} 34 inline int ask(int x){int an=0;while(x)an+=sum[x],x-=x&-x;return an;} 35 36 struct Node 37 { 38 int x,y,lca,val; 39 Node(int a=0,int b=0,int c=0,int d=0):x(a),y(b),lca(c),val(d){} 40 bool operator <(const Node &B)const{return val>B.val;} 41 }Q[N*5]; 42 43 int main(){ 44 while(~scanf("%d",&n)) 45 { 46 mst(g,0),mst(sum,0),ed=0; 47 F(i,1,n) 48 { 49 scanf("%d%d",&x,&y); 50 x++,y++; 51 adg(x,y),adg(y,x); 52 } 53 n++,idx=0,dfs1(1,0),dfs2(1,1); 54 scanf("%d",&m); 55 F(i,1,m) 56 { 57 scanf("%d%d",&x,&y); 58 x++,y++; 59 int lca=LCA(x,y); 60 Q[i]=Node(x,y,lca,dep[lca]); 61 } 62 sort(Q+1,Q+1+m); 63 int ans=0; 64 F(i,1,m) 65 { 66 int flag=(ask(dfsl[Q[i].x])||ask(dfsl[Q[i].y])); 67 if(!flag) 68 { 69 ans++; 70 add(dfsl[Q[i].lca],1); 71 add(dfsr[Q[i].lca]+1,-1); 72 } 73 } 74 printf("%d\n",ans); 75 } 76 return 0; 77 }