疫情控制
这道题 有点意思 让我迷了很久 包括我在写题解的时候 我都觉得不是很会写。(因为此时我还没有A掉这道题)
给同学讲了下题 然后把自己的代码覆盖了(那可是150+的代码啊都没了需重写o(╥﹏╥)o)
经过长达3h的思考 我终于想完了所有的细节问题和 一些check的问题及初始化 我觉得比较困难吧这道题。
当我写完 的时候发现调试比较恶心 头此时也比较晕 状态不太好了 巅峰时刻让打代码了。。。完了
终于打完了代码 一遍50 不我头脑不清醒 让我静静
好我知道了 貌似这个地方应该清零 但是我好像没有清零 这好像是可以导致错误的原因 改了 好像A了。。
这道题我觉得算是比较难的题目了,贪心 不好想 看了下书觉得不太会写 。
首先求 最短时间 好像根本不知道什么时候会最短 那就 二分吧 反正答案具有单调性
那我们可以有所有军队能行驶的距离了 ,此时 对于那些 到不了的根节点以下的节点肯定是能到多远到多远 越远越好
至于到了根节点的儿子节点的军队就有初步的资格去跨过根节点 来救援 至于救援不了的点那么自己管自己的就行了。
大体上的贪心细节请参考算法进阶竞赛指南。
//#include<bits/stdc++.h> #include<iostream> #include<cstdio> #include<iomanip> #include<cstring> #include<string> #include<cstdlib> #include<cmath> #include<algorithm> #include<cctype> #include<utility> #include<set> #include<bitset> #include<queue> #include<stack> #include<deque> #include<map> #include<vector> #include<ctime> #define ll long long #define INF 2147483646 using namespace std; char buf[1<<15],*fs,*ft; inline char getc() { return (fs==ft&&(ft=(fs=buf)+fread(buf,1,1<<15,stdin),fs==ft))?0:*fs++; } inline int read() { int x=0,f=1;char ch=getc(); while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getc();} while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getc();} return x*f; } inline void put(int x) { x<0?putchar('-'),x=-x:0; int num=0;char ch[50]; while(x)ch[++num]=x%10+'0',x/=10; num==0?putchar('0'):0; while(num)putchar(ch[num--]); putchar('\n');return; } const int MAXN=50002; int n,m,T; ll l,r,g[MAXN][20]; int a[MAXN],q[MAXN],f[MAXN][20],b[MAXN],vis[MAXN],son[MAXN],t,h,top; ll dis[MAXN],d[MAXN],c[MAXN],z[MAXN],s,en; int lin[MAXN<<1],nex[MAXN<<1],ver[MAXN<<1],e[MAXN<<1],len; vector<ll>p[MAXN]; inline void swap(ll &x,ll &y){ll t;t=x;x=y;y=t;} inline ll cmp(ll x,ll y){return x>y;} inline void add(int x,int y,int z) { ver[++len]=y; nex[len]=lin[x]; lin[x]=len; e[len]=z; } inline void bfs() { t=h=0; for(int i=lin[1];i;i=nex[i]) { int tn=ver[i]; vis[tn]=1;q[++t]=tn; b[++top]=i;son[tn]=top; } while(++h<t) { int te=q[h]; for(int i=lin[te];i;i=nex[i]) { int tn=ver[i]; if(vis[tn]==1)continue; q[++t]=tn;vis[tn]=1; f[tn][0]=te;g[tn][0]=e[i]; for(int j=1;j<=T;++j) { f[tn][j]=f[f[tn][j-1]][j-1]; g[tn][j]=g[tn][j-1]+g[f[tn][j-1]][j-1]; } } } } inline int dfs(int x,int father) { if(!son[x]&&vis[x])return 1; int flag=0; for(int i=lin[x];i;i=nex[i]) { int tn=ver[i]; if(tn==father)continue; flag=1; if(!dfs(tn,x))return 0; } return flag; } inline int check(ll x) { memset(vis,0,sizeof(vis)); memset(c,0,sizeof(c)); memset(z,0,sizeof(z)); for(int i=1;i<=top;++i)p[i].clear(); for(int i=1;i<=m;++i) { d[i]=a[i]; dis[i]=0; for(int j=T;j>=0;j--) { if(!f[d[i]][j])continue; if(dis[i]+g[d[i]][j]<=x) { dis[i]+=g[d[i]][j]; d[i]=f[d[i]][j]; } } int army=son[d[i]]; vis[d[i]]=1; if(army) { p[army].push_back(x-dis[i]); if(p[army].size()>1&&p[army][p[army].size()-2]<p[army][p[army].size()-1]) swap(p[army][p[army].size()-2],p[army][p[army].size()-1]); } } s=en=0; for(int i=1;i<=top;++i) { if(dfs(ver[b[i]],1)==0) { if(p[i].size()&&p[i][p[i].size()-1]<(e[b[i]]<<1))p[i].pop_back(); else z[++en]=e[b[i]]; } for(unsigned int j=0;j<p[i].size();++j)if(p[i][j]>=e[b[i]])c[++s]=p[i][j]-e[b[i]]; } sort(z+1,z+1+en,cmp); sort(c+1,c+1+s,cmp); for(int i=1,j=1;i<=en;++i,++j)if(c[j]<z[i])return 0; return 1; } int main() { //freopen("1.in","r",stdin); n=read(); for(int i=1;i<n;++i) { int x,y,z; x=read();y=read();z=read();r+=z; add(x,y,z);add(y,x,z); } T=(int)ceil(log(n*1.0)/log(2*1.0)); bfs(); m=read(); for(int i=1;i<=m;++i)a[i]=read(); if(m<top){put(-1);return 0;} while(l+1<r) { ll mid=(l+r)>>1; if(check(mid))r=mid; else l=mid; } if(check(l))put(l); else put(r); return 0; }