社区讨论
40分代码求调(码风简洁)
P1084[NOIP 2012 提高组] 疫情控制参与者 1已保存回复 0
讨论操作
快速查看讨论及其快照的属性,并进行相关操作。
- 当前回复
- 0 条
- 当前快照
- 1 份
- 快照标识符
- @loqutnpv
- 此快照首次捕获于
- 2023/11/09 15:15 2 年前
- 此快照最后确认于
- 2023/11/09 17:34 2 年前
C
#include<bits/stdc++.h>
#define int long long
#define re register
using namespace std;
inline int read(){
int x = 0,f = 1;char c = getchar();
for(;!isdigit(c);c = getchar())if( c == '-' )f = -1;
for(;isdigit(c);c = getchar())x = (x << 1) + (x << 3) + c - '0';
return x * f;
}
const int N = 6e4 + 5;
typedef pair<int,int> pii;
int n,m,mxt,ans,T;
int ph,pt,ps;
int id[N];
int fa[N][20],dis[N][20],dep[N];
bool status[N],need[N],still[N];
int tim[N];
pii h[N];
int head[N << 1],cnt;
struct edge{
int to,next,w;
}e[N << 1];
inline void add(int from,int to,int w){
e[++ cnt] = (edge){to , head[from] , w};
head[from] = cnt;
}
inline void init(){
queue<int> Q;
Q.push(1);
dep[1] = 1;
while( !Q.empty() ){
int x = Q.front();
Q.pop();
for(int i = head[x];i;i = e[i].next){
int to = e[i].to;
if( dep[to] )continue;
dep[to] = dep[x] + 1;
fa[to][0] = x;
dis[to][0] = e[i].w;
for(int j = 1;j <= T;j ++){
fa[to][j] = fa[fa[to][j - 1]][j - 1];
dis[to][j] = dis[to][j - 1] + dis[fa[to][j - 1]][j - 1];
}
Q.push( to );
}
}
}
inline bool dfs(int x){
bool leave = 0;
if( status[x] )return 1;
for(int i = head[x];i;i = e[i].next){
int to = e[i].to;
if( dep[to] < dep[x] )continue;
leave = 1;
if( !dfs( to ) )return 0;
}
if( !leave )return 0;
else return 1;
}
inline bool check(int lim){
memset( status , 0 , sizeof( status ) );
memset( tim , 0 , sizeof( tim ) );
memset( still , 0 , sizeof( still ) );
memset( h , 0 , sizeof( h ) );
memset( need , 0 , sizeof( need ) );
ph = pt = ps = 0;
for(int i = 1;i <= m;i ++){
int x = id[i],cnt = 0;
for(int j = T;j >= 0;j --){
if( fa[x][j] > 1 && cnt + dis[x][j] <= lim ){
cnt += dis[x][j];
x = fa[x][j];
}
}
if( fa[x][0] == 1 && cnt + dis[x][0] <= lim )h[++ ph] = make_pair( lim - cnt - dis[x][0] , x );
else status[x] = 1;
}
for(int i = head[1];i;i = e[i].next){
int to = e[i].to;
if( !dfs( to ) )need[to] = 1;
}
sort( h + 1 , h + ph + 1 );// first is rest time , second is idx
for(int i = 1;i <= ph;i ++){
if( need[h[i].second] && h[i].first < dis[h[i].second][0] )
need[h[i].second] = 0;
else tim[++ pt] = h[i].first;
}
for(int i = head[1];i;i = e[i].next){
int to = e[i].to;
if( need[to] )still[++ ps] = dis[to][0];
}
if( pt < ps )return 0;
sort( tim + 1 , tim + pt + 1 );
sort( still + 1 , still + ps + 1 );
int pi = 1,pj = 1;
while( pi <= pt && pj <= ps ){
if( tim[pi] >= still[pj] )pi ++,pj ++;
else pi ++;
}
if( pj > ps )return 1;
return 0;
}
signed main(){
int l = 0,r = 0,exist = 0;
n = read();
T = log2(n) + 1;
for(int i = 1;i < n;i ++){
int u = read(),v = read(),w = read();
add( u , v , w );
add( v , u , w );
mxt += w;
}
r = mxt;
init();
m = read();
for(int i = 1;i <= m;i ++)id[i] = read();
while( l <= r ){
int mid = ( l + r ) >> 1;
if( check( mid ) ){
exist = 1;
ans = mid;
r = mid - 1;
}
else l = mid + 1;
}
if( !exist )cout << -1 << endl;
else printf("%lld\n",ans);
return 0;
}
回复
共 0 条回复,欢迎继续交流。
正在加载回复...