拓扑排序基础 hdu1258,hdu2647

由这两题可知拓扑排序是通过“小于”关系加边建图的

hdu2647

/*
拓扑排序的原则是把“小于”看成有向边
此题反向建图即可
并且开num数组来记录每个点的应该得到的权值 
*/
#include<bits/stdc++.h>
#include<queue>
using namespace std;
#define maxn 20000
struct Edge{
    int to,nxt;
}edge[maxn<<1]; 
int head[maxn],tot,n,m;
void init(){
    memset(head,-1,sizeof head);
    tot=0;
}
void addedge(int u,int v){
    edge[tot].to=v;edge[tot].nxt=head[u];head[u]=tot++;
}
int in[maxn],num[maxn];
int main(){
    while(cin>>n>>m){
        init();
        memset(num,0,sizeof num);
        memset(in,0,sizeof in);
        while(m--){
            int u,v;
            cin>>u>>v;
            addedge(v,u);
            in[u]++;
        }
        
        queue<int>q;
        for(int i=1;i<=n;i++)
            if(in[i]==0)
                q.push(i);
        int ans=0,tot=0;
        while(!q.empty()){
            tot++;
            int u=q.front();
            q.pop();
            ans+=num[u];
            for(int i=head[u];i!=-1;i=edge[i].nxt){
                int v=edge[i].to;
                --in[v];
                if(in[v]==0){
                    num[v]=num[u]+1;
                    q.push(v);
                }
            }
        }
        if(tot<n)puts("-1");
        else printf("%d\n",ans+n*888);
    }    
}

 

posted on 2019-02-28 09:35  zsben  阅读(179)  评论(0编辑  收藏  举报

导航