HDU-5695-Gym Class(拓扑排序+优先队列)

来源:互联网 发布:vb计算圆的面积和周长 编辑:程序博客网 时间:2024/05/17 08:39

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=5695



Problem Description

众所周知,度度熊喜欢各类体育活动。 今天,它终于当上了梦寐以求的体育课老师。第一次课上,它发现一个有趣的事情。在上课之前,所有同学要排成一列, 假设最开始每个人有一个唯一的ID,从1到N,在排好队之后,每个同学会找出包括自己在内的前方所有同学的最小ID,作为自己评价这堂课的分数。麻烦的是,有一些同学不希望某个(些)同学排在他(她)前面,在满足这个前提的情况下,新晋体育课老师——度度熊,希望最后的排队结果可以使得所有同学的评价分数和最大。

Input

第一行一个整数T,表示T(1T30) 组数据。 对于每组数据,第一行输入两个整数NM(1N100000,0M100000),分别表示总人数和某些同学的偏好。 接下来M行,每行两个整数AB(1A,BN),表示ID为A的同学不希望ID为B的同学排在他(她)之前。你可以认为题目保证至少有一种排列方法是符合所有要求的。

Output

对于每组数据,输出最大分数 。

Sample Input
31 02 11 23 13 1
Sample Output
126



题解:拓扑序列贪心下每次取最大点,用优先队列就好



//#include <bits/stdc++.h>#include <iostream>#include <cstdio>#include <cstring>#include <queue>#include <vector>#include <algorithm>using namespace std;int Scan(){    int res=0,ch,flag=0;    if((ch=getchar())=='-')flag=1;    else if(ch>='0'&&ch<='9')res=ch-'0';    while((ch=getchar())>='0'&&ch<='9')res=res*10+ch-'0';    return flag?-res:res;}void Out(int a){    if(a>9)Out(a/10);    putchar(a%10+'0');}#define INF 0x3f3f3f3f#define bug cout<<"bug"<<endlconst int MAXN = 1e5+7;priority_queue<int>qi;vector<int> nod[MAXN];int link[MAXN];int head[MAXN];int num[MAXN];int main(){    int T;    int m,n;    cin>>T;    int cas=1;    int a,b;    while(T--)    {        scanf("%d%d",&n,&m);        memset(head,0,sizeof(head));        for(int i=0; i<n; ++i)nod[i].clear();        for(int i=0; i<m; ++i)        {            scanf("%d%d",&a,&b);            nod[a].push_back(b);            head[b]++;        }        for(int i=1; i<=n; ++i)            if(head[i]==0)                qi.push(i);        int temp=0;        while(!qi.empty())        {            int poi=qi.top();            qi.pop();            num[temp++]=poi;            int len=nod[poi].size();            for(int i=0; i<len; ++i)            {                head[ nod[poi][i] ]--;                if(head[ nod[poi][i] ]==0)                    qi.push(nod[poi][i]);            }        }        long long  ans=0;        int minn=INF;        for(int i=0; i<n ; ++i)        {            if(num[i]<minn)                minn=num[i];            ans+=minn;        }        printf("%I64d\n",ans);    }    return 0;}


0 0
原创粉丝点击