题目链接:hdu 5695 Gym Class 

题目意思:每个同学会找出包括自己在内的前方所有同学的最小ID,作为自己评价这堂课的分,最后的排队结果可以使得所有同学的评价分数和最大

思路:贪心的策略是尽量把id大的放在前面,拓扑排序是为了挑出没有排队限制的且数目尽可能大的id放在前面

/**************************************************************
    Problem:hdu 5695
    User: youmi
    Language: C++
    Result: Accepted
    Time:655 MS    
    Memory:3632 K
****************************************************************/
//#pragma comment(linker, "/STACK:1024000000,1024000000")
//#include<bits/stdc++.h>
#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <map>
#include <stack>
#include <set>
#include <sstream>
#include <cmath>
#include <queue>
#include <deque>
#include <string>
#include <vector>
#define zeros(a) memset(a,0,sizeof(a))
#define ones(a) memset(a,-1,sizeof(a))
#define sc(a) scanf("%d",&a)
#define sc2(a,b) scanf("%d%d",&a,&b)
#define sc3(a,b,c) scanf("%d%d%d",&a,&b,&c)
#define scs(a) scanf("%s",a)
#define sclld(a) scanf("%I64d",&a)
#define pt(a) printf("%d\n",a)
#define ptlld(a) printf("%I64d\n",a)
#define rep0(i,n) for(int i=0;i<n;i++)
#define rep1(i,n) for(int i=1;i<=n;i++)
#define rep_1(i,n) for(int i=n;i>=1;i--)
#define rep_0(i,n) for(int i=n-1;i>=0;i--)
#define Max(a,b) ((a)>(b)?(a):(b))
#define Min(a,b) ((a)<(b)?(a):(b))
#define lson (step<<1)
#define rson (lson+1)
#define esp 1e-6
#define oo 0x3fffffff
#define TEST cout<<"*************************"<<endl

using namespace std;
typedef long long ll;
int n,m;
const int maxn=100000+10;
struct side
{
    int v,next;
}e[maxn];
int T,head[maxn];
int in[maxn];
priority_queue<int>q;
void init()
{
    T=0;
    ones(head);
    zeros(in);
    q.empty();
}

void build(int u,int v)
{
    e[T].v=v;
    e[T].next=head[u];
    head[u]=T++;
}
void dfs(int u)
{
    for(int i=head[u];~i;i=e[i].next)
    {
        int v=e[i].v;
        in[v]--;
        if(in[v]==0)
            q.push(v);
    }
}
int main()
{
    #ifndef ONLINE_JUDGE
    freopen("in.txt","r",stdin);
    #endif
    int T_T;
    scanf("%d",&T_T);
    for(int kase=1;kase<=T_T;kase++)
    {
        //printf("Case #%d:\n",kase);
        sc2(n,m);
        init();
        for(int i=1;i<=m;i++)
        {
            int a,b;
            sc2(a,b);
            build(a,b);
            in[b]++;
        }
        for(int i=1;i<=n;i++)
            if(in[i]==0)
                q.push(i);
        ll ans=0;
        int mn=n+10;
        while(!q.empty())
        {
            int temp=q.top();
            mn=Min(temp,mn);
            q.pop();
            ans+=mn;
            dfs(temp);
        }
        ptlld(ans);
    }
    return 0;
}

 

posted on 2016-05-27 15:19  中子星  阅读(185)  评论(0编辑  收藏  举报