zoukankan      html  css  js  c++  java
  • P1084 疫情控制

    ——————————————————————————————————————————————————————

    邪门的贪心,需要处理很多情况,还要注意二分

    还要注意标记下传

    还要处理倍增

    还要双指针

    还是一道很好的题

    ——————————————————————————————————————

    #include<bits/stdc++.h>
    using namespace std;
    struct node{int nxt,dis,to;}eg[51000*2];
    #define ll long long
    int n,head[51000],m,ne,fa[51000][22],d[51000][22],a,b,c,id[51000],tag[51000];
    void adde(int from,int to,int dis)
    {eg[++ne].to=to;eg[ne].dis=dis;eg[ne].nxt=head[from];head[from]=ne;}
    struct nd{int it,re;}num[51000];
    struct nod{int ti,val;}q[51000];
    int cmp(nd x,nd y){return x.re<y.re;}
    int cmp2(nod a,nod b){return a.val<b.val;}
    void dfs(int u,int f){
        for(int i=head[u];i;i=eg[i].nxt)
        {
            int v=eg[i].to;
            if(v==f)continue;
            fa[v][0]=u;d[v][0]=eg[i].dis;
            dfs(v,u);
        }
    }
    void dfs2(int u,int f){
        if(tag[u])return;
        bool flg=0;tag[u]=1;
        for(int i=head[u];i;i=eg[i].nxt)
        {
            int v=eg[i].to;
            if(v==f)continue;
            dfs2(v,u);
            flg=1;
            if(!tag[v])tag[u]=0;
        }
        if(!flg)tag[u]=0;
    }
    int check(ll w)
    {
        memset(tag,0,sizeof(tag));
        int cnt=0,sum=0;
        for(int i=1;i<=m;i++)
        {
            ll rest=w;
            int di=id[i];
            for(int j=16;j>=0;j--)if(rest-d[di][j]>=0&&fa[di][j]>1){rest-=d[di][j];di=fa[di][j];}
            if(fa[di][0]!=1||(rest<d[di][0]))tag[di]=1;
            else {
                num[++cnt].it=di;
                num[cnt].re=rest-d[di][0];
                }    
        }
        dfs2(1,1);
        for(int i=head[1];i;i=eg[i].nxt)
        if(!tag[eg[i].to]){q[++sum].ti=eg[i].to;q[sum].val=eg[i].dis;}
        sort(num+1,num+1+cnt,cmp);
        sort(q+1,q+1+sum,cmp2);
        int pos=1;
        for(int i=1;i<=cnt;++i) {
            if(!tag[num[i].it]) tag[num[i].it]=1;
            else if(num[i].re>=q[pos].val)tag[q[pos].ti]=1;
            while(tag[q[pos].ti]&&pos<=sum) ++pos;
            int t;
            for(t=pos;t<=sum;t++)
            {
                
            }
        }
        return pos>sum;
    }
    int main()
    {
        ll r=0,l=0,mid,ans;
        cin>>n;
        for(int i=1;i<n;i++)
        {cin>>a>>b>>c;adde(a,b,c);adde(b,a,c);r+=c;}
        cin>>m;
        for(int i=1;i<=m;i++)cin>>id[i];
        dfs(1,0);
        for(int i=1;i<=16;i++)for(int j=1;j<=n;j++){fa[j][i]=fa[fa[j][i-1]][i-1];d[j][i]=d[j][i-1]+d[fa[j][i-1]][i-1];    }
        while(l<=r)
        {    mid=(l+r)/2;
            if(check(mid))ans=mid,r=mid-1;
            else l=mid+1;
        }
        cout<<ans;
    }
  • 相关阅读:
    思考的容器:结构
    思维的结构-结构是思维的组织形式-系统思维
    分层 抽象 复杂 认知
    NoSQL 简介
    什么是数据库ACID?
    sqlite3 多线程和锁 ,优化插入速度及性能优化
    Architecture of SQLite
    关系模型我的理解
    科学理论--抽象
    认识的三个层次
  • 原文地址:https://www.cnblogs.com/SFWR-YOU/p/11104947.html
Copyright © 2011-2022 走看看