RE求助
查看原帖
RE求助
540177
wyf_sinon楼主2024/7/19 16:43

这是蒟蒻用过为数不多的multiset RE60pts 大概率是erase的时候出错了

#include<bits/stdc++.h>
using namespace std;
#define int long long 
const int N=1e5+10;
int n,m;
int h[N],ne[N*2],enter[N*2],edge[N*2],idx; 
int cnt;
int mx;
bool f[N];
void link(int u,int v,int w)
{
    ne[idx]=h[u];
    edge[idx]=w;
    enter[idx]=v;
    h[u]=idx++;
}
multiset<int> lian[N] ; 
int dfs(int pos,int fa,int mid) //处理子链 优先组成m的链 带回不能组成m的最长链 
{ 
	lian[pos].clear();
    for(int i=h[pos];~i;i=ne[i])//便利所有的边
    {
        int y=enter[i];
        if(y==fa) continue;
        int res=dfs(y,pos,mid)+edge[i];//带上来的链
        if(res>=mid) { cnt++; continue ; } 
        lian[pos].insert( res )  ; //链数+1
    }     
    auto it = lian[pos].begin();
    bool f = 0 ;
    while( !lian[pos].empty() && lian[pos].size()>1 )
    { 
    	int min_lian=*it;
    	while( min_lian + *lian[pos].lower_bound(mid-min_lian) < mid ) 
    	{
    		++it ;
    		min_lian = * it ;
			if( it == lian[pos].lower_bound(mid-min_lian) || lian[pos].lower_bound(mid-min_lian) == lian[pos].begin()  ) f = 1 ;
			if( f ) break ;
		}
		if( f ) break ;
        auto b = it ;
    	lian[pos].erase(b);
    	lian[pos].erase( lian[pos].lower_bound(mid-min_lian) );
    	cnt++;
	}
	if( !lian[pos].empty() ) return *prev(lian[pos].end());
	else return 0;
}
bool check(int mid)
{
    dfs(1,0,mid); 
    return cnt>=m;
}
signed main()
{
    memset(h,-1,sizeof h);
    scanf("%lld%lld",&n,&m);
    for(int i=1;i<n;i++)
    {
        int u,v,w;
        scanf("%lld%lld%lld",&u,&v,&w);
        link(u,v,w); link(v,u,w); 
        mx+=w;
    }
    int l=0,r=mx;
    while(l<=r)//二分最小值
    {
        cnt=0;
        int mid=(l+r)>>1;
        if( check(mid) ) l=mid+1; 
        else r=mid-1;
    }
    printf("%lld",l-1);
}

玄关awa

2024/7/19 16:43
加载中...