BZOJ2809可合并堆或启发式合并

一个启发式合并的题目。可以使用可合并堆,但是我觉的不必要,

唯一 的坑点是,优先队列耗费的内存比multiset太多太多,简直可以被淘汰了。用mutiset直接爆内存。所以。相信科学。发现set可以但是priority_queue不可以直接换掉。;。。。

上代码:

#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 3
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
//#include 
//#include 

#pragma warning(disable:4996)
using namespace std;

#define mp make_pair
#define PB push_back
typedef long long ll;
typedef long long LL;
typedef unsigned long long ull;
typedef double db;
typedef long double ldb;
typedef pair  pii;
typedef pair  pll;
typedef pair  pli;
typedef pair  pdd;

int IT_MAX = 1 << 21;
const int MOD = 1000000007;
const int INF = 1034567891;
const ll LL_INF = 1234567890123456789ll;
const db PI = 3.141592653589793238;
const ldb ERR = 1E-12;
const ll mod = 1e6+3 ;
ll qpow(ll x, ll y){
    if(y == 0) return 1 ;
    ll tmp = qpow(x , y/2) ;
    if(y & 1) return tmp * tmp % mod * x % mod ;
    return tmp * tmp % mod ;
}
#define mem(x ,y ) memset(x , y , sizeof(x))
#define lowbit(x) (x & (-x))
/****/
/****/
vector  v[200010] ;
multisetq[200010] ;
map  sum ;
int a[200010] ;
int b[200010] ;
ll ans = 0 ;
ll n , m ;
void unionset(int i ,int j){
    if(q[i].size() < q[j].size()) swap(q[i] , q[j]) , swap(sum[i] ,sum[j]) ;
    sum[i] += sum[j] ;
    for(multiset::iterator mi=q[j].begin() ; mi!=q[j].end() ; mi++){
        int x = *mi;
        q[i].insert(x) ;
    }
    multiset::iterator mi=q[i].end() ; mi -- ;
    multiset::iterator tmp ;
    int sz = q[i].size() ;
    while(sz && sum[i] > m){
        int x = *mi ;
        q[i].erase(mi --);
        sum[i] -= x ; sz -- ;
    }
}
void dfs(int ts){
    if(ts != 0){
        q[ts].insert(a[ts]) ;
        sum[ts] += a[ts] ;
    }
    for(int i=0;i> n >> m ;
    for(int i=1;i<=n;i++){
        int ta,tb,tc; scanf("%d%d%d" , &ta,&tb,&tc) ;
        v[ta].PB(i) ;
        a[i] = tb ; b[i] = tc ;
    }
    dfs(0) ;
    cout << ans <


你可能感兴趣的:(BZOJ2809可合并堆或启发式合并)