拓扑排序

拓扑排序

算法思想

1.入度数组ru[],记录是否存在环的情况;
2.利用bfs()将入度为0的依次压入队列,将其所指向的点入度减一;
3.在排序的过程中实现题目目的;

例题

HDU2647
思路:
1.先反向建边,x比y多则将y指向x;
2.用一个val[]数组记录每一个点最大需要多花费的钱,依次向上更新,排序的过程就完成了,数据的更新;
## 代码

#include <bits/stdc++.h>
using namespace std;
const int N=1e5+55;
int head[N],ru[N],val[N];
int ans,cnt,n,m;
struct node{
    int to,next;
}mp[N];
void add(int x, int y)
{
    mp[cnt].to=y;
    mp[cnt].next=head[x];
    head[x]=cnt++;
}
bool tuop()
{
    queue<int >q;
    int t=0;
    for(int i=1;i<=n;++i){
        if(!ru[i]){
            q.push(i);
            val[i]=0;
        }
    }
    while(!q.empty()){
        int u=q.front();
        q.pop();
        ans=ans+val[u]+888;      //没有点指向该点了,直接算出所需费用;
        ++t;                      //记录是否有环的变量;
        for(int i=head[u];~i;i=mp[i].next){
            int to=mp[i].to;
            val[to]=max(val[to],val[u]+1);       //要取最大值,画图易得;
            ru[to]--;
            if(!ru[to]){
                q.push(to);
            }
        }
    }
    if(t!=n) return false;
    return true;
}
int main()
{
    while(scanf("%d%d",&n,&m)!=EOF){
        int x,y;
        ans=cnt=0;
        memset(head,-1,sizeof(head));
        memset(ru,0,sizeof(ru));
        memset(val,-1,sizeof(val));
        for(int i=0;i<m;++i){
            scanf("%d%d",&x,&y);
            add(y,x);
            ru[x]++;
        }
        bool k=tuop();
        if(k){
            printf("%d\n",ans);
        }
        else{
            printf("-1\n");
        }
    }
    return 0;
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章