hdu5695-优先队列&拓扑排序-Gym Class

本文探讨了使用优先队列解决特定问题时遇到的挑战,并通过对比介绍了一种更有效的解决方案——拓扑排序。文章分析了两种方法的实现细节,并通过代码示例展示了如何正确应用这些算法。

https://vjudge.net/problem/HDU-5695
第一次以为直接用优先队列就行。
报要求的数,优先级放在那个数后面
对于相同优先级的数,比较他们的大小,大的在前,小的在后
(因为大的在前可以保证这样子结果大)
。。
都没想到 拓扑排序那里面去。、如果这种关系出现了图形的结构,那么只用这种方法怎么行么。。
附上我的错误代码。。
aaa数组 ,我保存的,如果是一个数被 很多数约定要在后面,那么他就在最后面。,。。这样嫩过样例我就 没考虑。。

#include <iostream>
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
struct cmp2{
  bool operator()(pair<int,ll>a,pair<int,ll> b)
{  if(a.first==b.first)
    return a.second<b.second;
    return a.first<b.first;
};
};
priority_queue<pair<int,ll> >q;
const int maxn=100006;
int main()
{   int a[maxn];
    ll  b[maxn];
    int aaa[maxn];
    int t;
    int m,n;
    bool vis[maxn];
    scanf("%d",&t);
    while(t--){
          while(!q.empty()) q.pop();
          scanf("%d%d",&m,&n);
        for(int i=1;i<=m;i++){

            aaa[i]=m+1;
        }
          memset(vis,false,sizeof(vis));
          for(int i=1;i<=n;i++){
             scanf("%d%lld",&a[i],&b[i]);
             if(!vis[b[i]]){vis[b[i]]=true;
                aaa[b[i]]=min(aaa[b[i]],a[i]-1);}//太年轻
             //q.push(make_pair(a[i]-1,b[i]));}
           }
           for(int i=1;i<=m;i++){
             if(vis[i])
             q.push(make_pair(aaa[i],i));
           }
           for(int i=1;i<=m;i++){
               if(!vis[i])
                q.push(make_pair(i,(ll)i));
           }
           ll ans=1e17;
           ll sum=0;
           while(!q.empty()){
              pair<int,ll> u=q.top();
               ans=min(ans,u.second);
               //cout<<ans<<endl;
                //cout<<u.second<<endl;
               sum+=ans;
               q.pop();
           }
           printf("%lld\n",sum);




    }



    return 0;
}
#include <iostream>
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const int maxn=100006;
priority_queue<int>q;
vector<int>G[maxn];
int index[maxn];
int main()
{   int a;
  int   b;
    int t;
    int m,n;
    scanf("%d",&t);
    while(t--){
          while(!q.empty()) q.pop();
          scanf("%d%d",&m,&n);
          for(int i=0;i<maxn;i++)
            G[i].clear();
          memset(index,0,sizeof(index));
          for(int i=1;i<=n;i++){
             scanf("%d%d",&a,&b);
             G[a].push_back(b);
             index[b]++;
             //q.push(make_pair(a[i]-1,b[i]));}
           }
           for(int i=1;i<=m;i++){
             if(!index[i])
             q.push(i);
           }
           ll sum=0;
           int sma=m;
           while(!q.empty()){
              int u=q.top();
               q.pop();
               for(int i=0;i<G[u].size();i++){
                index[G[u][i]]--;
                if(!index[G[u][i]])
                     q.push(G[u][i]);
               }
               //cout<<u<<endl;
               sma=min(sma,u);
               sum+=1ll*sma;
           }
           printf("%lld\n",sum);
    }
    return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值