题目描述
题解
如果 Σ a i < ( n − 1 ) x \Sigma a_i < (n-1)x Σai<(n−1)x ,说明不可以。
否则证明其一定可以。
假设 a 1 ≤ a 2 ≤ . . . ≤ a n a_1 \le a_2 \le ... \le a_n a1≤a2≤...≤an ,则如果 a n + a 1 < x a_n+a_1<x an+a1<x ,则 a 1 ≤ a 2 ≤ . . . ≤ a n < x − a 1 a_1 \le a_2 \le ... \le a_n <x-a_1 a1≤a2≤...≤an<x−a1 ,则 Σ a i < ( n − 1 ) x − ( n − 2 ) a 1 \Sigma a_i < (n-1)x-(n-2)a_1 Σai<(n−1)x−(n−2)a1 ,矛盾。因此我们可以每次让最大的和其相邻的任意一点合并即可。
代码
#include<bits/stdc++.h>
#define M make_pair
using namespace std;
#define LL long long
const int N=6e5+5;
int n,m,f[N],R[N],g[N],p[N],t[N];
LL a[N],X;
vector<pair<int,int>>e[N];
struct O{
LL x;int u;
};
bool operator < (O A,O B){
return A.x<B.x;
}
priority_queue<O>q;
int get(int x){
return x==f[x]?x:f[x]=get(f[x]);
}
int main(){
scanf("%d%d%lld",&n,&m,&X);
for (int i=1;i<=n;i++)
scanf("%lld",&a[i]),
a[0]+=a[i],g[i]=p[i]=f[i]=i;
for (int i=1,u,v;i<=m;i++)
scanf("%d%d",&u,&v),
t[u]++,t[v]++,
e[u].push_back(M(v,i)),
e[v].push_back(M(u,i));
if (a[0]<X*(n-1)){puts("NO");return 0;}
puts("YES");
for (int i=1;i<=n;i++)
q.push((O){a[i],i});
while(!q.empty()){
O u=q.top();q.pop();
if (get(u.u)!=u.u) continue;
int x=p[u.u];bool fl=1;
while(fl && x){
for (int i=t[x]-1,v;~i;i--){
v=e[x][i].first;t[x]--;
if (get(v)==u.u) continue;
v=get(v);a[u.u]+=a[v]-X;
printf("%d\n",e[x][i].second);
R[g[u.u]]=p[v];g[u.u]=g[v];
f[v]=u.u;fl=0;break;
}
if (fl) x=R[x],p[u.u]=x;
}
if (!fl) q.push((O){a[u.u],u.u});
}
return 0;
}