hdu 6203 ping ping ping(贪心+树状数组+dfs序)

题目链接:hdu 6203 ping ping ping

题意:

给你一棵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 }
View Code

 

posted @ 2017-10-17 21:02  bin_gege  阅读(276)  评论(0编辑  收藏  举报