zoukankan      html  css  js  c++  java
  • PKU3321

    开始写的是用线段树的模型 由于结构的差异 线段较烦 节点中只能记录父节点 然后在维护节点中COUNT值的时候 需要不断地从叶节点开始从下到上对count进行更新 正好和线段树相反 结果超时了
    这是因为 如果数据中的树是一棵很高的树的话 维护COUNT值会耗时很大
    下面是上面思想的超时代码
    (用邻接表也许更省时一点,不过想想如果用精简的树状数组会更美观一些)
    #include<stdio.h>
    #include
    <string.h>

    struct Tree
    {
        
    int count;
        
    bool have;
        
    int f;
    }
    ;

    Tree fork[
    100010];
    int con[100010][2];
    bool b[100010];
    int count[100010];
    bool v[100010];
    int n, m;
    char op;
    int opN;

    void build(int f)
    {
        fork[f].have
    =1;
        fork[f].count
    =1;
        
    int i;
        
    for(i=0;i<n-1;i++)
        
    {
            
    if(b[i]==0)
            
    {
                
    if(con[i][0]==f)
                
    {
                    b[i]
    =1;
                    fork[con[i][
    1]].f=f;
                    build(con[i][
    1]);
                }

                
    if(con[i][1]==f)
                
    {
                    b[i]
    =1;
                    fork[con[i][
    0]].f=f;
                    build(con[i][
    0]);
                }

            }

        }

    }



    void buildLeaf()
    {
        
    bool end=1;
        memset(count,
    0,sizeof(count));
        
    int i;
        
    for(i=0;i<n-1;i++)
        
    {
            
    if(v[con[i][0]]==0 && v[con[i][1]]==0 )
            
    {
                count[con[i][
    0]]++;
                count[con[i][
    1]]++;
                end
    =0;
            }

        }

        
    for(i=2;i<=n;i++)
        
    {
            
    if(count[i]==1)
            
    {
                fork[fork[i].f].count
    +=fork[i].count;
                v[i]
    =1;
            }

        }

        
    if(!end)
            buildLeaf();
    }


    void opera()
    {
        
    if(op=='C')
        
    {
            
    if(fork[opN].have==1)
            
    {
                fork[opN].have
    =0;
                fork[opN].count
    --;
                
    int f=fork[opN].f;
                
    while(f>=1)
                
    {
                    fork[f].count
    --;
                    
    if(f>1)
                        f
    =fork[f].f;
                    
    else
                        
    break;
                }

            }

            
    else
            
    {
                fork[opN].have
    =1;
                fork[opN].count
    ++;
                
    int f=fork[opN].f;
                
    while(f>=1)
                
    {
                    fork[f].count
    ++;
                    
    if(f>1)
                        f
    =fork[f].f;
                    
    else
                        
    break;
                }

            }

        }

        
    else
        
    {
            printf(
    "%d\n",fork[opN].count);
        }

    }



    int main()
    {
        
    while(scanf("%d",&n)==1)
        
    {
            memset(b,
    0,sizeof(b));
            
    int i;
            
    for(i = 0; i < n-1 ; i++)
            
    {
                scanf(
    "%d%d",&con[i][0],&con[i][1]);
            }

            build(
    1);
            memset(v,
    0,sizeof(v));
            buildLeaf();
            scanf(
    "%d",&m);
            
    for(i=0;i<m;i++)
            
    {
                scanf(
    "\n%c%d"&op, &opN);
                opera();
            }

        }


        
    return 0;
    }
  • 相关阅读:
    HTTP协议详解(真的很经典)
    几点建议,让Redis在你的系统中发挥更大作用
    Redis能干啥?细看11种Web应用场景
    Java中使用Jedis操作Redis
    java的锁机制——synchronized
    web开发中的两把锁之数据库锁:(高并发--乐观锁、悲观锁)
    一分钟教你知道乐观锁和悲观锁的区别
    $^,$@,$?,$<,$(@D),$(@F) of makefile
    linux shared lib 使用与编译
    makefile learning
  • 原文地址:https://www.cnblogs.com/SQL/p/914677.html
Copyright © 2011-2022 走看看