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

    传送门

    解法:

    这道题虽然思路不会太难

    但是代码较难实现 可能是我太菜了

    思路就是二分答案

    在答案范围内将军队尽量向上提(注意不能提到跟节点)

    然后考虑子树见转移

    对于根节点的子节点进行转移

    要是爬上来消耗掉的时间还足以转移改军队

    则将其加到根节点上准备转移

    对于要救助的子节点进行转移即可

    请参考代码(调了我一天) 要是你能看懂

    代码:

    #include<iostream>
    #include<cstdio>
    #include<algorithm>
    #include<cstring>
    #include<vector>
    #include<cmath>
    #include<queue>
    #include<map>
    #define inf 2000000000
    #define min(x,y) ((x)<(y)?(x):(y))
    #define max(x,y) ((x)>(y)?(x):(y))
    #define rep(i,a,b) for(int i=(a);i<=(b);++i)
    #define dwn(i,a,b) for(int i=(a);i>=(b);--i)
    using namespace std;
    typedef long long ll;
    int n,m,root=1,cnt=0,dep[50010],f[50010][18],lg2[50010],pnt[50010];
    vector<ll> pos[50010];vector<int> rec;
    bool v[50010];
    ll d[50010],ans=-1,up=0;
    queue<int> que;
    int head[50010],tot=1;
    struct EDGE
    {
        int to,nxt,d;
    }edge[100010];
    void add(int u,int v,int d)
    {
        edge[++tot].nxt=head[u];
        edge[tot].to=v;
        edge[tot].d=d;
        head[u]=tot;
    }
    void bfs()
    {
        d[root]=0,dep[root]=1;
        que.push(root);
        while(!que.empty())
        {
            int x=que.front();que.pop();
            for(int i=head[x];i;i=edge[i].nxt)
            {
                int y=edge[i].to;
                if(dep[y]) continue;
                d[y]=d[x]+edge[i].d;
                up=max(up,d[y]);
                dep[y]=dep[x]+1;
                f[y][0]=x;
                rep(i,1,lg2[dep[y]]) f[y][i]=f[f[y][i-1]][i-1];
                que.push(y);
            }
        }
    }
    bool sortcmp(ll a,ll b)
    {
        return a>b;
    }
    bool recsort(int a,int b)
    {
    	return a>b;
    }
    void dfs(int x)
    {
        if(v[x]) return;
        for(int i=head[x];i;i=edge[i].nxt)
        {
            int y=edge[i].to;
            if(dep[x]>dep[y]) continue;
            dfs(y);
            v[x]=v[y];
            if(!v[x]) return;
        }
    }
    bool check(ll k)
    {
        memset(v,0,sizeof(v));
        rep(i,1,n)pos[i].clear();
    	rec.clear();
        rep(i,1,m)
        {
            int y=pnt[i];ll dis=k;
            dwn(i,lg2[dep[y]-2],0)
                if(d[y]-d[f[y][i]]<=dis&&dep[f[y][i]]>=2)
                    dis=dis-d[y]+d[f[y][i]],y=f[y][i];
            if(dep[y]==2){pos[y].push_back(dis);}
            v[y]=1;
        }
        for(int i=head[root];i;i=edge[i].nxt)
        {
            int x=edge[i].to;
            v[x]=0;
            dfs(x);
            if(pos[x].empty()&&!v[x]){rec.push_back(edge[i].d);continue;}
            sort(pos[x].begin(),pos[x].end(),sortcmp);
            for(int j=0;j<int(pos[x].size())-(v[x]?0:1);++j)
            {
                ll dis=pos[x][j];
                if(dis>=edge[i].d) pos[root].push_back(dis-edge[i].d);
            }
            if(!v[x]&&pos[x][pos[x].size()-1]>=2*edge[i].d)
    			pos[root].push_back(pos[x][pos[x].size()-1]-edge[i].d),rec.push_back(edge[i].d);
        }
        if(rec.empty()) return 1;
        if(pos[root].size()<rec.size()) return 0;
        sort(rec.begin(),rec.end(),recsort);
        sort(pos[root].begin(),pos[root].end(),sortcmp);
        for(int i=0;i<rec.size();++i)
        {
            if(pos[root][i]<rec[i]) return 0;
        }
        return 1;
    }
    int main()
    {
        scanf("%d",&n);
        rep(i,2,50000) lg2[i]=lg2[i>>1]+1;
        rep(i,1,n-1)
        {
            int u,v,d;
            scanf("%d%d%d",&u,&v,&d);
            if(u==1||v==1) cnt++;
            add(u,v,d),add(v,u,d);
        }
        bfs();
        scanf("%d",&m);
        if(cnt>m) {printf("-1
    ");return 0;}
        rep(i,1,m)
        {
            scanf("%d",&pnt[i]);
        }
        ll l=0,r=2*up;
        while(l<=r)
        {
            ll mid=(l+r)>>1;
            if(check(mid)) ans=mid,r=mid-1;
            else l=mid+1;
        }
        printf("%lld
    ",ans);
        return 0;
    }
    
    
  • 相关阅读:
    洛谷P1508 Likecloud-吃、吃、吃 [2017年4月计划 动态规划10]
    洛谷P1855 榨取kkksc03 [2017年4月计划 动态规划 09]
    洛谷P1164 小A点菜 [2017年4月计划 动态规划08]
    洛谷P1244 [NOI2000] 青蛙过河 [2017年4月计划 动态规划07]
    洛谷P1757 通天之分组背包 [2017年4月计划 动态规划06]
    洛谷P1877 [HAOI2012]音量调节 [2017年4月计划 动态规划05]
    洛谷P1474 [USACO 2.3]货币系统 Money Systems [2017年4月计划 动态规划04]
    洛谷P1832 A+B Problem(再升级) [2017年4月计划 动态规划03]
    洛谷P1968 美元汇率[2017年4月计划 动态规划02]
    洛谷P2347 砝码称重 [2017年4月计划 动态规划01]
  • 原文地址:https://www.cnblogs.com/MYsBlogs/p/11147283.html
Copyright © 2011-2022 走看看