HDU 5695 Gym Class (拓扑排序、贪心、优先队列)

Gym Class

Time Limit: 6000/1000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others)
Total Submission(s): 2887    Accepted Submission(s): 1084

Problem Description
众所周知,度度熊喜欢各类体育活动。
今天,它终于当上了梦寐以求的体育课老师。第一次课上,它发现一个有趣的事情。在上课之前,所有同学要排成一列, 假设最开始每个人有一个唯一的ID,从1到 N,在排好队之后,每个同学会找出包括自己在内的前方所有同学的最小ID,作为自己评价这堂课的分数。麻烦的是,有一些同学不希望某个(些)同学排在他(她)前面,在满足这个前提的情况下,新晋体育课老师——度度熊,希望最后的排队结果可以使得所有同学的评价分数和最大。
 
input
第一行一个整数 T,表示T(1T30) 组数据。
对于每组数据,第一行输入两个整数NM(1N100000,0M100000),分别表示总人数和某些同学的偏好。
接下来M行,每行两个整数AB(1A,BN),表示ID为A的同学不希望ID为B的同学排在他(她)之前。你可以认为题目保证至少有一种排列方法是符合所有要求的。
 
Output
对于每组数据,输出最大分数 。
 
Sample Input
3 1 0 2 1 1 2 3 1 3 1
 
Sample Output
1 2 6
 

题目分析

本题和常规的拓扑排序很像,都是N个人,M对关系,不同的是,需要评分的和最大

先抛开拓扑排序不谈,对于这种积分方式,自然是将ID大的尽量往前排这种贪心方法最为合适

在贪心的基础上又要满足拓扑排序,自然很容易想到优先队列,每次出队的都是入度为0中ID最大的点

注意有两个坑点,一个是longlong 另一个是输入输出超时

#include<bits/stdc++.h>
using namespace std;

long long  T,x,y,n,m,minn,anss,into[100005];
vector<int>mp[100005];
priority_queue<int,vector<int>>q;

void bfs()
{
    while(!q.empty())
    {
        int now=q.top();
        q.pop();
        if(minn>now)
        {
            minn=now;
        }
        anss+=minn;
        for(int i=0;i<mp[now].size();i++)
        {
            int next=mp[now][i];
            into[next]--;
            if(into[next]==0)
            {
                q.push(next);
            }
        }
    }
}

int main()
{
    ios::sync_with_stdio(false); //不写会TLE 
    cin>>T;
    while(T--)
    {
        memset(mp,0,sizeof(mp));
        memset(into,0,sizeof(into));
        anss=0;
        minn=0x3f3f3f3f;
        cin>>n>>m;
        while(m--)
        {
            cin>>x>>y;
            mp[x].push_back(y);
            into[y]++;
        }
        for(int i=1;i<=n;i++)
        {
            if(into[i]==0)
            {
                q.push(i);
            }
        }
        bfs();
        cout<<anss<<endl;
    }
}

猜你喜欢

转载自www.cnblogs.com/dyhaohaoxuexi/p/12405318.html