zoukankan      html  css  js  c++  java
  • 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;
        }
    }
  • 相关阅读:
    2018年10月22日-Python day1
    Python list(列表)功能详解
    剑指offer(4):重建二叉树
    剑指offer(3):从尾到头打印单链表
    剑指offer(2):替换空格
    机器学习实战:第九章 树回归
    ubuntu 中查找文件的命令
    关于 c++ primer plus 中valarray类使用例程的一个记录
    vim 最基本操作
    如何在VS2015中使用strcpy函数
  • 原文地址:https://www.cnblogs.com/dyhaohaoxuexi/p/12405318.html
Copyright © 2011-2022 走看看