拓扑排序

算法很简单,就是将图存下(同时各个点的入度要用数据记录)遍历点,找出入度为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; }


你可能感兴趣的:(拓扑排序)