zoukankan      html  css  js  c++  java
  • poj2114树分治

    题意:给你一棵树,每条边有权值,求有没有一条链使得权值和为k

    题解:和上一题类似,依旧是树分治,只是我们储存结果的时候是判断加起来为k的点对数,刚开始本来想用map存答案,结果就t了,后来用了vector,数组等各种,最后用数组,绝望的把memset改成for就过了。

    学到一个新的点:如果我们调用了m[i](m是map),不管m[i]是不是0,当我们遍历map时就会出现这个数,但是second=0

    #include<map>
    #include<set>
    #include<cmath>
    #include<queue>
    #include<stack>
    #include<vector>
    #include<cstdio>
    #include<cassert>
    #include<iomanip>
    #include<cstdlib>
    #include<cstring>
    #include<iostream>
    #include<algorithm>
    #define fi first
    #define se second
    #define mp make_pair
    #define pb push_back
    #define pii pair<int,int>
    #define C 0.5772156649
    #define pi acos(-1.0)
    #define ll long long
    #define mod 1000000007
    #define ls l,m,rt<<1
    #define rs m+1,r,rt<<1|1
    
    using namespace std;
    using namespace __gnu_cxx;
    
    const double g=10.0,eps=1e-7;
    const int N=20000+10,maxn=400000+10,inf=0x3f3f3f;
    
    struct edge{
        int to,Next,c;
    }e[maxn];
    int cnt,head[N];
    int sz[N],zx[N],dis[N];
    int k,son[N],sonsz;
    bool vis[N];
    void add(int u,int v,int c)
    {
        e[cnt].to=v;
        e[cnt].c=c;
        e[cnt].Next=head[u];
        head[u]=cnt++;
    }
    void dfssz(int u,int f,int &sum)
    {
        sum++;
        sz[u]=1;
        for(int i=head[u];~i;i=e[i].Next)
        {
            int x=e[i].to;
            if(x==f||vis[x])continue;
            dfssz(x,u,sum);
            sz[u]+=sz[x];
        }
    }
    void dfszx(int u,int f,int sum,int &ans,int &id)
    {
        zx[u]=sum-sz[u];
        for(int i=head[u];~i;i=e[i].Next)
        {
            int x=e[i].to;
            if(x==f||vis[x])continue;
            dfszx(x,u,sum,ans,id);
            zx[u]=max(zx[u],sz[x]);
        }
        if(ans>zx[u])
        {
            ans=zx[u];
            id=u;
        }
    }
    int findzx(int root)
    {
        int sum=0,ans=inf,id=0;
        dfssz(root,-1,sum);
        dfszx(root,-1,sum,ans,id);
        return id;
    }
    void dfsdis(int u,int f)
    {
        son[sonsz++]=dis[u];
        for(int i=head[u];~i;i=e[i].Next)
        {
            int x=e[i].to;
            if(x==f||vis[x])continue;
            dis[x]=dis[u]+e[i].c;
            dfsdis(x,u);
        }
    }
    int ok1()
    {
        sort(son,son+sonsz);
      /*  for(int i=0;i<ma.size();i++)cout<<ma[i]<<" ";
        cout<<endl;
        cout<<"---------"<<endl;*/
        int ans=0;
        for(int i=0;i<sonsz;i++)
        {
            int p1=upper_bound(son,son+sonsz,k-son[i])-son;
            int p2=lower_bound(son,son+sonsz,k-son[i])-son;
            ans+=p1-p2;
        }
        return ans/2;
    }
    void dfsson(int u,int f)
    {
        son[sonsz++]=dis[u];
        for(int i=head[u];~i;i=e[i].Next)
        {
            int x=e[i].to;
            if(x==f||vis[x])continue;
            dfsson(x,u);
        }
    }
    int solve(int root)
    {
        int p=findzx(root);
        dis[p]=0;
        sonsz=0;
        dfsdis(p,-1);
        int ans=ok1();
        for(int i=head[p];~i;i=e[i].Next)
        {
            int x=e[i].to;
            if(vis[x])continue;
            sonsz=0;
            dfsson(x,p);
            ans-=ok1();
        }
        vis[p]=1;
        for(int i=head[p];~i;i=e[i].Next)
        {
            int x=e[i].to;
            if(vis[x])continue;
            ans+=solve(x);
        }
        return ans;
    }
    void init()
    {
        cnt=0;
        memset(head,-1,sizeof head);
    }
    int main()
    {
       /* ios::sync_with_stdio(false);
        cin.tie(0);*/
        int n;
        while(scanf("%d",&n),n)
        {
            init();
            for(int i=1;i<=n;i++)
            {
                int a,b;
                while(scanf("%d",&a))
                {
                    if(!a)break;
                    scanf("%d",&b);
                    add(i,a,b);
                    add(a,i,b);
                }
            }
            while(1)
            {
                for(int i=1;i<=n;i++)vis[i]=0;
                scanf("%d",&k);
                if(!k)break;
                if(solve(1)>0)puts("AYE");
                else puts("NAY");
            }
            puts(".");
        }
        return 0;
    }
    /*******************
    
    ********************/
    View Code
  • 相关阅读:
    hibernate一级缓存和二级缓存的区别
    springmvc中的controller是单例的
    Java 冒泡排序
    spring mvc做上传图片,文件小于10k就不生成临时文件了
    java程序生成二维码
    MySQL调优
    根据从redis缓存的数据查询出来,在从数据库中取出所有的数据,俩个数据进行比较,去掉重复,剩下库中新插入的数据,取出新数据,然后把redis中的缓存数据清空把从数据库中查出来的所有数据放到redis缓存中
    找出list中的不同元素、删除两个list中相同的对象
    PowerDesigner如何将消失的工具栏显示出来
    Oracle基础(九) Oracle的体系结构
  • 原文地址:https://www.cnblogs.com/acjiumeng/p/7817596.html
Copyright © 2011-2022 走看看