HDU 5695 Gym Class (拓扑排序&贪心)
题意:若干人排队,每人一个权值,给若干优先级顺序,求怎么排队(在特定权值计算下)权值和最大。
思路:贪心思想:在满足优先级的情况下权值越大排在越前面
时间复杂度:O(N+M)
#include<bits/stdc++.h>
using namespace std;
priority_queue<int>q;
const int N=1e5+5;
typedef long long ll;
ll in[N],n,m;
vector<int>v[N];
void init(){
for(int i=1;i<=n;i++)
in[i]=0,v[i].clear();
}
ll toposort(){
ll ans=0,minn=0x3f3f3f3f;
for(int i=1;i<=n;i++) if(!in[i]) q.push(i);//入度为0的点是排在最前面
while(q.size()){//优先队列越大越在前面 因为要是总和最大 所以越大越前面是最优的
ll now=q.top();q.pop();
minn=min(minn,now);//又因为每个答案贡献是最小的那个值,所以就相当于取前面队列的最小值。
ans+=minn;
for(auto i:v[now])
if(--in[i]==0) q.push(i);
}
return ans;
}
int main(){
int t;
ios::sync_with_stdio(false);cin.tie(0);//当输入超过1e5时 注意关闭流同步
cin>>t;
while(t--){
cin>>n>>m;
init();//初始化
while(m--){
int a,b;
cin>>a>>b;
v[a].push_back(b);
in[b]++;
}
cout<<toposort()<<endl;
}
return 0;
}