首先不得不承认这题写残疾了,本来是优先队列随便搞一下就过了(确保弹出来的箭能杀死兔子),这里贴一下当时另一种贪心思想写的,运用了并查集,对于箭贪心,每次杀能杀死的最大的兔子之后得到解,这里要用并查集动态维护一下x的箭杀什么兔子,乱搞一气也算过了。
#include <iostream>
#include <queue>
#include <algorithm>
#include <map>
using namespace std;
int n,m,nn;
int rib[50005];
struct A{
int a,qb;
}arr[50005];
int index[100005];
int f[50005];
int vis[50005];
int cc[50005];
bool operator < (A a1,A a2){
return a1.qb<a2.qb;
}
int fin(int x){
int r=x;
while(f[r]!=r)
r=f[r];
return r;
}
void mer(int a,int b){
int fx,fy;
fx=fin(a);
fy=fin(b);
if(fx!=fy)
f[fx]=fy;
}
void solve(){
long long ans=0;
int cnt=0;
for(int i=0;i<m;i++){
int x=fin(index[arr[i].a]);
if(x!=0){
vis[x]--;
if(vis[x]==0)
mer(x,x-1);
ans+=(long long)arr[i].qb;
cnt++;
}
if(cnt==n)
break;
}
if(cnt==n){
cout<<ans<<endl;
}
else{
cout<<"No Solution"<<endl;
}
}
int main()
{
cin>>n>>m;
for(int i=0;i<n;i++){
cin>>rib[i];
}
for(int i=0;i<m;i++){
cin>>arr[i].a>>arr[i].qb;
}
sort(arr,arr+m);
sort(rib,rib+n);
for(int i=0;i<50005;i++){
f[i]=i;
}
int num=0;
int N=0;
for(int i=0;i<100005;i++){
if(num<n){
if(i<rib[num]){
index[i]=N;
}
else{
N++;
index[i]=N;
vis[N]++;
num++;
while(rib[num]==rib[num-1]){
vis[N]++;
num++;
}
}
}
else{
index[i]=N;
}
}
solve();
return 0;
}