UVA1205 Color a Tree
Preface
题目链接
双倍经验
三倍经验
这是一道经典题。
Statement
有一个
Solution
感性地理解可以发现
考虑把这个思路推广到更多结点的情况,设有两个序列
这样每次把最大的和父亲合并即可,时间复杂度 priority_queue + 并查集优化成
Summary
经典 exchange arguments 题,溜。
Code
//AC!
#include<iostream>
#include<cstdio>
#include<queue>
//#define int long long
#define repe(i,l,r) for(int (i)=l;(i)<=r;(i)++)
#define rep(i,n) for(int (i)=1;(i)<=n;(i)++)
#define FOR(i,r,l) for(int (i)=r;(i)>=l;(i)--)
#define INF 0x3f3f3f
#define pii pair<int,int>
#define ll long long
#define mpr make_pair
#define pb push_back
#define F first
#define S second
#define sz(v) (int)((v).size())
#define ALL(v) (v).begin(),(v).end()
#define rsort(v) sort(ALL(v),greater<int>())
#define lb(v,x) (int)(lower_bound(ALL(v),x)-v.begin())
#define ub(v,x) (int)(upper_bound(ALL(v),x)-v.begin())
#define uni(v) v.resize(unique(ALL(v))-v.begin())
using namespace std;
int read(){int sum=0,f=1;char c;c=getchar();while(c<'0'||c>'9'){if(c=='-')f=-1;c=getchar();}while(c>='0'&&c<='9'){sum=(sum<<1)+(sum<<3)+(c-'0');c=getchar();}return sum*f;}
void out(int x){if(x<0){x=-x;putchar('-');}if(x>=10)out(x/10);putchar(x%10+'0');}
void die(string s){cout<<s<<endl;exit(0);}
int fast(int a,int b,int P){int res=1;if(P<=0){while(b){if(b&1)res=res*a;a=a*a;b>>=1;}}else{while(b){if(b&1)res=res*a%P;a=a*a%P;b>>=1;}}return res;}
using namespace std;
const int N=1010;
int n,r,c[N],fa[N];
struct node{
int sum,siz,fat;
}tree[N];
bool vis[N];
priority_queue<pair<double,int> > pq;
int getfa(int u){
if(fa[u]==u)return u;
return fa[u]=getfa(fa[u]);
}
int main(){
while(1){
n=read(),r=read();
if(!n)break;
int ans=0;
for(int i=1;i<=n;i++){
c[i]=read();
fa[i]=i;
tree[i].sum=c[i];
tree[i].siz=1;
ans+=c[i];
vis[i]=0;
if(i!=r)pq.push(mpr(1.0*c[i],i));
}
int u,v;
for(int i=1;i<n;i++){
u=read(),v=read();
tree[v].fat=u;
}
while(!pq.empty()){
u=pq.top().S;
pq.pop();
if(vis[u])continue;
vis[u]=1;
int rt=getfa(tree[u].fat);
ans+=tree[rt].siz*tree[u].sum;
tree[rt].sum+=tree[u].sum;
tree[rt].siz+=tree[u].siz;
fa[u]=rt;
if(rt!=r){
pq.push(mpr(1.0*tree[rt].sum/tree[rt].siz,rt));
}
}
out(ans),putchar('\n');
}
return 0;
}