拓扑排序+优先队列+邻接表。
#include<cstdio> #include<iostream> #include<cstring> #include<cmath> #include<queue> #include<algorithm> using namespace std; const int N = 100005; struct node { int v,next; } s[N]; int head[N],degree[N],a[N]; int cnt,n,m,temp; void add(int a,int b) { s[cnt].v=b; s[cnt].next=head[a]; head[a]=cnt++; degree[b]++; } void topo() { priority_queue<int,vector<int>,less<int> >Q; for(int l=1; l<=n; l++) { if(!degree[l]) Q.push(l); } temp=0; while(!Q.empty()) { int top=Q.top(); Q.pop(); a[temp++]=top; for(int i=head[top]; i!=-1; i=s[i].next) { int v=s[i].v; degree[v]--; if(!degree[v]) { Q.push(v); } } } } int main() { int T; scanf("%d",&T); while(T--) { scanf("%d%d",&n,&m); cnt=0; memset(head,-1,sizeof(head)); memset(degree,0,sizeof(degree)); for(int i=0; i<m; i++) { int a,b; scanf("%d%d",&a,&b); add(a,b); } topo(); int flag=1000000; __int64 ans=0; //没想到答案超int 哇了一次。 for(int i=0; i<temp; i++) { flag=min(flag,a[i]); ans=ans+flag; } printf("%I64d\n",ans); } return 0; } 题目地址:http://acm.hdu.edu.cn/showproblem.php?pid=5695