码迷,mamicode.com
首页 > 其他好文 > 详细

P1084 疫情控制

时间:2019-06-04 17:45:15      阅读:92      评论:0      收藏:0      [点我收藏+]

标签:优先   define   sed   top   dfs   using   sign   pre   scan   

妈耶,因为自己脑残调了2个小时(我一直以为自己贪心写错了..)

for(int j=19;j>=0;j--){
            if(f[a[i].now][j]&&a[i].rest>=dis[a[i].now][j]&&f[a[i].now][j]!=1){
                a[i].rest-=dis[a[i].now][j];//出错原因竟是这2行写反了!?这种sb错误是人可以犯的吗..
                a[i].now=f[a[i].now][j];
            }
        }

做法就是先安排不可以到根的第一个儿子的军队,找出没安排的儿子

然后将可以到根的第一个儿子的军队放到优先队列里去

将要安排的儿子放到另一个里

然后逐个判断就行了..

有点啰嗦的逻辑...

贪心:若一个军队rest最小,他到他可以到的距离最小的儿子是最优的,无论儿子是否在now.

这样的贪心乍一看好像有问题,但是其实是可以的(因为它和mid是有关的)

其实还是不行的,因为这样有的mid可以过,有的mid过不了,不符合单调性...

while(pq1.size()){
        int now=pq1.top().now,rest=pq1.top().rest;
        pq1.pop();
        if(!pq2.size()){
            break;
        }
        while(pq2.size()&&used[pq2.top().second])
               pq2.pop();
           if(pq2.size()==0)break;
        //if(rest<=dis[now][0]&&used[now]==0)used[now]=1;
        if(rest>=-pq2.top().first){
            used[pq2.top().second]=1;
            pq2.pop();
        }
        else {
            used[now]=1;
        }
    }

 所以还是加上注释的内容为好..

#include<bits/stdc++.h>
#define ll long long
using namespace std;
const int N=5e4+7;
int n,c[N],f[N][20],m;
ll l,r,mid,dis[N][20];
bool v[N],qwe[N],v2[N],v3[N],used[N];
vector <pair<int,int> > edge[N];
struct army{
    int now;
    ll rest;
    bool operator < (const army &b)const {
        return rest>b.rest;
    }
}a[N];
priority_queue <army> pq1;
priority_queue <pair<ll,int> > pq2;
void dfs(int x,int fa){
    v[x]=1;
    f[x][0]=fa;
    for(int i=1;i<20;i++){
        f[x][i]=f[f[x][i-1]][i-1];
        dis[x][i]=dis[f[x][i-1]][i-1]+dis[x][i-1];
    }
    for(unsigned int i=0;i<edge[x].size();i++){
        int y=edge[x][i].first,z=edge[x][i].second;
        if(v[y])continue;
        dis[y][0]=z;
        dfs(y,x);
    }
}
void dfs2(int x){
    v[x]=1;
    used[x]=1;
    if(v2[x]==1){
        used[x]=1;
        return;
    }
    if(edge[x].size()==1){
        used[x]=0;
        return;
    }
    for(unsigned int i=0;i<edge[x].size();i++){
        int y=edge[x][i].first;
        if(v[y])continue;
        dfs2(y);
        used[x]&=used[y];
    }
}
bool check(){
    memset(v,0,sizeof(v));
    memset(v2,0,sizeof(v2));
    memset(used,0,sizeof(used));
    while(pq2.size())pq2.pop();
    while(pq1.size())pq1.pop();
    for(int i=1;i<=m;i++){
        a[i].now=c[i];
        a[i].rest=mid;
        for(int j=19;j>=0;j--){
            if(f[a[i].now][j]&&a[i].rest>=dis[a[i].now][j]&&f[a[i].now][j]!=1){
                a[i].rest-=dis[a[i].now][j];
                a[i].now=f[a[i].now][j];
            }
        }
        if(qwe[a[i].now]){
            a[i].rest-=dis[a[i].now][0];
            pq1.push(a[i]);
        }
        else v2[a[i].now]=1;
    }
    dfs2(1);
    for(unsigned int i=0;i<edge[1].size();i++){
        int y=edge[1][i].first;
        if(used[y])continue;
        pq2.push(make_pair(-dis[y][0],y));
    }
    while(pq1.size()){
        int now=pq1.top().now,rest=pq1.top().rest;
        pq1.pop();
        if(!pq2.size()){
            break;
        }
        while(pq2.size()&&used[pq2.top().second])
               pq2.pop();
           if(pq2.size()==0)break;
        if(rest<=dis[now][0]&&used[now]==0)used[now]=1;
        else if(rest>=-pq2.top().first){
            used[pq2.top().second]=1;
            pq2.pop();
        }
        else {
            used[now]=1;
        }
    }
    while(pq2.size()&&used[pq2.top().second])
           pq2.pop();
    return pq2.size()==0;
}
int main(){
    //freopen("in.in","r",stdin);    
    //freopen("out.out","w",stdout);
    cin>>n;
    for(int i=1;i<n;i++){
        int x,y,z;
        scanf("%d%d%d",&x,&y,&z);
        edge[x].push_back(make_pair(y,z));
        edge[y].push_back(make_pair(x,z));
        r+=z;
    }
    cin>>m;
    for(unsigned int i=0;i<edge[1].size();i++){
        int y=edge[1][i].first;
        qwe[y]=1;
    }
    for(int i=1;i<=m;i++){
        int x;
        scanf("%d",&x);
        c[i]=x;
    }
    dfs(1,0);
    while(l<r){
        mid=510;
        if(check())r=mid;
        else l=mid+1;
    }
    printf("%lld\n",l);
    return 0;
}

 

P1084 疫情控制

标签:优先   define   sed   top   dfs   using   sign   pre   scan   

原文地址:https://www.cnblogs.com/Hikigaya/p/10974774.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!