zoukankan      html  css  js  c++  java
  • [poj3417]Network(LCA+树形dp)

    题意:给出一棵无根树,然后下面再给出m条边,把这m条边连上,每次你去两条边,规定一条是树边,一条是新边,问有多少种方案能使树断裂。

    解题关键:边权转化为点权,记录每条边被环覆盖的次数,通过val[a]++,val[b]++,val[lca(a,b)]-=2,来控制每个点上面的边,所以树的顶点要去掉。

    好久没1A了,开心

      1 //#pragma comment(linker, "/STACK:1024000000,1024000000")
      2 #include<cstdio>
      3 #include<cstring>
      4 #include<algorithm>
      5 #include<cstdlib>
      6 #include<cmath>
      7 #include<iostream>
      8 #include<vector>
      9 typedef long long ll;
     10 using namespace std;  
     11 const int maxn=101000; 
     12 const int maxm=30;  
     13 int _pow[maxm],m,n;  
     14 int head[maxn],tot;
     15 int ver[maxn*2],depth[maxn*2],first[maxn],rmq[maxn*2][25],id;//5个数组,注意哪个需要乘2 
     16 int pre[maxn],val[maxn];
     17 int ans;
     18 inline int read(){
     19     char k=0;char ls;ls=getchar();for(;ls<'0'||ls>'9';k=ls,ls=getchar());
     20     int x=0;for(;ls>='0'&&ls<='9';ls=getchar())x=(x<<3)+(x<<1)+ls-'0';
     21     if(k=='-')x=0-x;return x;
     22 }
     23 
     24 struct edge{
     25     int to,nxt;  
     26 }e[maxn*2];//链式前向星建树 
     27 
     28 void init(){
     29     memset(head,-1,sizeof head); 
     30     tot=0;
     31     id=0;
     32     ans=0;
     33 }
     34 
     35 void add_edge(int u,int v){  
     36     e[tot].to=v;
     37     e[tot].nxt=head[u];
     38     head[u]=tot++;
     39 }
     40   
     41 void dfs(int u,int fa,int dep){
     42     ver[++id]=u;//第i个访问到的结点编号 
     43     depth[id]=dep;//第i个访问到的结点深度  
     44     first[u]=id;
     45     for(int i=head[u];i!=-1;i=e[i].nxt){
     46         int v=e[i].to;
     47         if(v==fa) continue;
     48         //pre[v]=u;
     49         dfs(v,u,dep+1);
     50         ver[++id]=u;//后序遍历,再次访问父节点 
     51         depth[id]=dep;
     52     }
     53 }
     54 
     55 void rmq_init(int n){
     56     int k=int(log(n)/log(2));
     57     for(int i=1;i<=n;++i)    rmq[i][0]=i;  
     58     for(int j=1;j<=k;++j){  
     59         for(int i=1;i+_pow[j]-1<=n;++i){//因为存的是索引 
     60             int a=rmq[i][j-1],b=rmq[i+_pow[j-1]][j-1];  
     61             rmq[i][j]=depth[a]<depth[b]?a:b;
     62         }
     63     }
     64 }
     65   
     66 int rmq_query(int l,int r){
     67     int k=int(log(r-l+1.0)/log(2.0));  
     68     int a=rmq[l][k],b=rmq[r-_pow[k]+1][k];  
     69     return depth[a]<depth[b]?a:b;
     70 }//返回的依然是索引 
     71   
     72 int LCA(int u,int v){
     73     int x=first[u],y=first[v];  
     74     if(x>y)swap(x,y);  
     75     int res=rmq_query(x,y);  
     76     return ver[res]; 
     77 }
     78 void dfs(int u,int fa){
     79     for(int i=head[u];i!=-1;i=e[i].nxt){
     80         int v=e[i].to;
     81         if(v==fa) continue;
     82         dfs(v,u);
     83         val[u]+=val[v];
     84     }
     85     if(val[u]==1) ans++;
     86     else if(!val[u]&&u!=1) ans+=m;
     87 }
     88 
     89 int main(){
     90     for(int i=0;i<maxm;++i)    _pow[i]=1<<i; //预处理2^n 
     91     int k,a,b;
     92     n=read();m=read();
     93     init();
     94     //for(int i=1;i<=n;i++) val[i]=read();
     95     for(int i=0;i<n-1;++i){
     96         a=read(),b=read();
     97         add_edge(a,b);
     98         add_edge(b,a);
     99     }
    100     dfs(1,-1,0);
    101     rmq_init(2*n-1);
    102     for(int i=0;i<m;++i){
    103         a=read();b=read();
    104         val[a]++,val[b]++,val[LCA(a,b)]-=2;
    105     }
    106     dfs(1,-1);
    107     printf("%d
    ",ans);
    108     
    109     return 0;
    110 }
  • 相关阅读:
    Push UIViewController with different orientation to previous
    shouldAutoRotate Method Not Called in iOS6
    UIScrollView中图片放大后不居中,或居中后移动有偏差解决办法
    iOS7隐藏状态栏 status Bar
    【struts2】Struts2的系统架构
    【struts2】核心概念
    【struts2】struts2的execAndWait拦截器使用
    【struts2】<s:url>标签
    【sql】CHARINDEX
    【js】在js中加HTML注释标签的原因?
  • 原文地址:https://www.cnblogs.com/elpsycongroo/p/7475092.html
Copyright © 2011-2022 走看看