题目链接: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 ",a) #define ptlld(a) printf("%I64d ",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: ",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; }