P1084 疫情控制
Posted hikigaya
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了P1084 疫情控制相关的知识,希望对你有一定的参考价值。
妈耶,因为自己脑残调了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 疫情控制的主要内容,如果未能解决你的问题,请参考以下文章