算法很简单,就是将图存下(同时各个点的入度要用数据记录)遍历点,找出入度为0的点然后输出,同时要把这个点已经对应的边删除掉,不断循环操作。
hdu2467
这题大概意思是老板发工资,分为不同层次的员工,所以发的工资要不同,每个层次都依赖于上个层次,于是抽象成拓扑排序
这题数据比较大用邻接表,时间 15ms 广搜+邻接表这速度太快了,大神的代码比较牛逼,这里借用下。
#include<iostream> #include<algorithm> #include<stdlib.h> #include<string.h> #include<math.h> #include<string> #include<vector> #include<queue> #include<list> using namespace std; typedef long long lld; typedef unsigned int ud; #define Inf INT_MAX/2//int最大 #define Min(x,y) (x)<(y)?(x):(y) #define Max(x,y) (x)>(y)?(x):(y) #define MemsetMax(a) memset(a,100,sizeof a) #define MemsetZero(a) memset(a,0,sizeof a) #define MemsetMin(a) memset(a,-1,sizeof a) #define PQ priority_queue #define Q queue #define N 10002 #define M N*2 struct Node { int v,next; }edge[M]; int head[N],ind[N]; int money[N]; int n,m; int main() { while(scanf("%d%d",&n,&m)!=EOF) { MemsetMin(head); MemsetZero(ind); for(int i=1;i<=n;i++) money[i]=888; for(int i=1;i<=m;i++) { int u,v; scanf("%d%d",&u,&v); edge[i].v=u; edge[i].next=head[v]; head[v]=i; ind[u]++; } int ans=0,sum=0; Q<int>q; for(int i=1;i<=n;i++) if(ind[i]==0) { q.push(i); } while(!q.empty()) { int e=q.front(); q.pop(); ans+=money[e]; sum++; for(int j=head[e];j!=-1;j=edge[j].next) { if(--ind[edge[j].v]==0) { q.push(edge[j].v); money[edge[j].v]=money[e]+1; } } } if(sum!=n) ans=-1; printf("%d\n",ans); } return 0; }