题目描述
H 国有 n 个城市,这 n 个城市用 n-1 条双向道路相互连通构成一棵树,1 号城市是首都,
也是树中的根节点。
H 国的首都爆发了一种危害性极高的传染病。当局为了控制疫情,不让疫情扩散到边境
城市(叶子节点所表示的城市),决定动用军队在一些城市建立检查点,使得从首都到边境
城市的每一条路径上都至少有一个检查点,边境城市也可以建立检查点。但特别要注意的是,
首都是不能建立检查点的。
现在,在 H 国的一些城市中已经驻扎有军队,且一个城市可以驻扎多个军队。一支军队可以在有道路连接的城市间移动,并在除首都以外的任意一个城市建立检查点,且只能在
一个城市建立检查点。一支军队经过一条道路从一个城市移动到另一个城市所需要的时间等
于道路的长度(单位:小时)。
请问最少需要多少个小时才能控制疫情。注意:不同的军队可以同时移动。
输入输出格式
输入格式:
第一行一个整数 n,表示城市个数。
接下来的 n-1 行,每行 3 个整数,u、v、w,每两个整数之间用一个空格隔开,表示从
城市 u 到城市 v 有一条长为 w 的道路。数据保证输入的是一棵树,且根节点编号为 1。
接下来一行一个整数 m,表示军队个数。
接下来一行 m 个整数,每两个整数之间用一个空格隔开,分别表示这 m 个军队所驻扎
的城市的编号。
输出格式:
共一行,包含一个整数,表示控制疫情所需要的最少时间。如果无法控制疫情则输出-1。
输入输出样例
输入样例#1:
4 1 2 1 1 3 2 3 4 3 2 2 2输出样例#1:
3说明
【输入输出样例说明】
第一支军队在 2 号点设立检查点,第二支军队从 2 号点移动到 3 号点设立检查点,所需
时间为 3 个小时。
【数据范围】
保证军队不会驻扎在首都。
对于 20%的数据,2≤ n≤ 10;
对于 40%的数据,2 ≤n≤50,0<w <10^5;
对于 60%的数据,2 ≤ n≤1000,0<w <10^6;
对于 80%的数据,2 ≤ n≤10,000;
对于 100%的数据,2≤m≤n≤50,000,0<w <10^9。
NOIP 2012 提高组 第二天 第三题
又理解错题了,是同时的。
往往不容易直接进行最优解的时候都要考虑一下二分。那么就给你一个限定时间,你在限定时间之内完成就好了。
我们会发现,其实你越往上走,覆盖的路径越多,所以每个点都尽量往上走。
有些点走到了根,有些点没有,没有走到根的点就直接对子树做贡献。走到根的点要合理分配,使得在限定时间内覆盖子树。
这时如果子树没有被覆盖,那么从根往下走一步就好了。
很容易想到贪心,两个都排序,大的对大的,小的对小的。
但是有一个问题,有时候你从子树走到根,然后走不回来了。【但其实他留在那棵子树上可能更好【相当于他下来完全不用时间的
考虑一个子树,从他出发的点剩余时间最少的是x,如果x不能走回来,那么就让x留在那子树上,否则这种情况不用管【因为都能走回来了,就不用管了
为什么走不会来,就直接留下呢,因为这样你覆盖这棵子树一定用了其他点,说明这个点比x更强,那么如果x能做到的事,这个点更能做到,所以x不需做别的,管好这棵子树就好。
【倍增打错了,捂脸
1 #include<cstdio> 2 #include<cstdlib> 3 #include<cstring> 4 #include<iostream> 5 #include<algorithm> 6 #include<queue> 7 #include<cmath> 8 using namespace std; 9 #define Maxn 50010 10 #define Maxd 25 11 #define INF 0xfffffff 12 #define LL long long 13 14 struct node 15 { 16 LL x,y,next,c; 17 }t[Maxn*2];LL len; 18 LL first[Maxn]; 19 LL n,m; 20 21 void ins(LL x,LL y,LL c) 22 { 23 t[++len].x=x;t[len].y=y;t[len].c=c; 24 t[len].next=first[x];first[x]=len; 25 } 26 27 LL mymin(LL x,LL y) {return x<y?x:y;} 28 29 bool am[Maxn]; 30 LL ff[Maxn],d[Maxn][Maxd],f[Maxn][Maxd],id[Maxn]; 31 LL dis[Maxn],dep[Maxn]; 32 33 void dfs(LL x,LL fa) 34 { 35 for(LL i=1;i<=18;i++) 36 d[x][i]=d[f[x][i-1]][i-1],f[x][i]=f[f[x][i-1]][i-1]; 37 if(fa==1) ff[x]=x; 38 else ff[x]=ff[fa]; 39 for(LL i=first[x];i;i=t[i].next) if(t[i].y!=fa) 40 { 41 LL y=t[i].y; 42 d[y][0]=t[i].c;f[y][0]=x; 43 dis[y]=dis[x]+t[i].c;dep[y]=dep[x]+1; 44 dfs(y,x); 45 } 46 } 47 48 LL mn[Maxn]; 49 bool g[Maxn]; 50 void dfs2(LL x,LL fa) 51 { 52 LL ans=0; 53 bool ok=1,sm=0; 54 for(LL i=first[x];i;i=t[i].next) if(t[i].y!=fa) 55 { 56 sm=1; 57 LL y=t[i].y; 58 dfs2(y,x); 59 if(!g[y]) ok=0; 60 } 61 if(am[x]||(ok&&sm)) g[x]=1; 62 } 63 64 struct hp 65 { 66 LL x,w; 67 }q1[Maxn],q2[Maxn]; 68 69 LL lf[Maxn]; 70 71 bool cmp(hp x,hp y) {return x.w<y.w;} 72 73 bool us[Maxn]; 74 bool check(LL x) 75 { 76 memset(am,0,sizeof(am)); 77 memset(g,0,sizeof(g)); 78 memset(lf,-1,sizeof(lf)); 79 for(LL i=first[1];i;i=t[i].next) mn[t[i].y]=-1; 80 LL xx; 81 for(LL i=1;i<=m;i++) 82 { 83 LL now=id[i];xx=x; 84 for(LL j=18;j>=0;j--) 85 { 86 if((1<<j)<=dep[now]&&dis[now]-dis[f[now][j]]<=xx) 87 { 88 xx-=dis[now]-dis[f[now][j]]; 89 now=f[now][j]; 90 } 91 } 92 am[now]=1; 93 if(now==1) lf[i]=x-dis[id[i]]; 94 if(now==1&&(mn[ff[id[i]]]==-1||lf[mn[ff[id[i]]]]>lf[i])) mn[ff[id[i]]]=i; 95 } 96 dfs2(1,0); 97 LL l1=0,l2=0; 98 for(LL i=1;i<=m;i++) if(lf[i]!=-1) q1[++l1].x=i,q1[l1].w=lf[i]; 99 // for(LL i=1;i<=m;i++) if(id[i]==1) q1[++l1].x=0,q1[l1].w=x; 100 for(LL i=first[1];i;i=t[i].next) 101 { 102 LL y=t[i].y; 103 if(!g[y]) q2[++l2].x=y,q2[l2].w=t[i].c; 104 } 105 memset(g,0,sizeof(g)); 106 sort(q1+1,q1+1+l1,cmp); 107 sort(q2+1,q2+1+l2,cmp); 108 LL j=1,i; 109 // LL k=l1; 110 if(l1<l2) return 0; 111 for(i=1;i<=l2;i++)if(mn[q2[i].x]!=-1&&g[mn[q2[i].x]]==0&&lf[mn[q2[i].x]]<q2[i].w) 112 { 113 g[mn[q2[i].x]]=1; 114 q2[i].x=-1; 115 } 116 117 for(i=1;i<=l2;i++) if(q2[i].x!=-1) 118 { 119 while(g[q1[j].x]&&j<=l1) j++; 120 // if(j>l1) return 0; 121 /*if(mn[q2[i].x]!=-1&&g[mn[q2[i].x]]==0&&lf[mn[q2[i].x]]<q2[i].w) 122 { 123 g[mn[q2[i].x]]=1; 124 continue; 125 }*/ 126 /*else*/ if(mn[q2[i].x]==-1||lf[mn[q2[i].x]]>=q2[i].w) 127 { 128 while((g[q1[j].x]||q1[j].w<q2[i].w)&&j<=l1) j++; 129 } 130 if(j>l1) return 0; 131 g[q1[j].x]=1; 132 j++; 133 } 134 return 1; 135 } 136 137 void ffind(LL l,LL r) 138 { 139 LL ans=-1; 140 while(l<r) 141 { 142 LL mid=(l+r)>>1; 143 if(check(mid)) ans=mid,r=mid; 144 else l=mid+1; 145 } 146 if(check(l)) ans=l; 147 printf("%lld ",ans); 148 } 149 150 int main() 151 { 152 scanf("%lld",&n); 153 len=0; 154 memset(first,0,sizeof(first)); 155 LL sum=0; 156 for(LL i=1;i<n;i++) 157 { 158 LL x,y,c; 159 scanf("%lld%lld%lld",&x,&y,&c); 160 ins(x,y,c);ins(y,x,c); 161 sum+=c; 162 } 163 memset(am,0,sizeof(am)); 164 scanf("%lld",&m); 165 for(LL i=1;i<=m;i++) 166 { 167 LL x; 168 scanf("%lld",&x); 169 am[x]++; 170 id[i]=x; 171 } 172 f[1][0]=0; 173 dis[0]=0;dep[0]=0; 174 dfs(1,0); 175 ffind(0,sum); 176 return 0; 177 }
【打得丑并且调了一个晚上,捂脸= =
2016-11-17 07:52:50