• 博客园logo
  • 会员
  • 周边
  • 新闻
  • 博问
  • 闪存
  • 众包
  • 赞助商
  • Chat2DB
    • 搜索
      所有博客
    • 搜索
      当前博客
  • 写随笔 我的博客 短消息 简洁模式
    用户头像
    我的博客 我的园子 账号设置 会员中心 简洁模式 ... 退出登录
    注册 登录
magicat
博客园    首页    新随笔    联系   管理    订阅  订阅
DAG(有向无环图)拓扑排序 模板

应用:

  1. 判断有向图是否存在环 代码源图论初级课程题单报名免费
  2. 求一个图的拓扑序   
  3. 在2.的基础上求字典序最小拓扑序,优先队列实现


拓扑排序板子:

选择入度为0的点作为起始点

// d代表入度,用vector存的图
void toposort()
{
    queue<int> q;
    for(int i=1;i<=n;i++)
        if(d[i]==0)
            q.push(i);
    while(!q.empty())
    {
        int t = q.front();  q.pop();
        for(auto it : son[t])
            if(--d[it]==0)
                q.push(it);
    }
}

 

 

有向图环判断

 

int d[100010];
int n,m;
vector<int> son[100010];
void toposort()
{
    queue<int> q;
    for(int i=1;i<=n;i++)
        if(d[i]==0)
            q.push(i);
    while(!q.empty())
    {
        int t = q.front();  q.pop();
        for(auto it : son[t])
            if(--d[it]==0)
                q.push(it);

    }
    for(int i=1;i<=n;i++)
        if(d[i]>0)
        {
            cout<<"Yes"<<endl;   return;
        }
    
    cout<<"No"<<endl;
}
void solve()
{   
    cin>>n>>m;
    for(int i=1;i<=m;i++)
    {
        int x,y;    cin>>x>>y;
        son[x].push_back(y);
        d[y]++;
    }
    toposort();
    return;
}
int main()
{
    std::ios::sync_with_stdio(false);   cin.tie(nullptr), cout.tie(nullptr);
    solve();    
    return 0;
}

字典序最小拓扑序

int d[100010];
int n,m;
vector<int> son[100010];
void toposort()
{
    priority_queue<int,vector<int>,greater<int>> q;
    for(int i=1;i<=n;i++)
        if(d[i]==0)
            q.push(i);
    while(!q.empty())
    {
        int t = q.top();  q.pop();
        cout<<t<<" ";
        for(auto it : son[t])
            if(--d[it]==0)
                q.push(it);
    }

}
void solve()
{   
    cin>>n>>m;
    for(int i=1;i<=m;i++)
    {
        int x,y;    cin>>x>>y;
        son[x].push_back(y);
        d[y]++;
    }
    toposort();
    return;
}
int main()
{
    std::ios::sync_with_stdio(false);   cin.tie(nullptr), cout.tie(nullptr);
    solve();    
    return 0;
}

 

新年礼物,DAG拓扑图上动态规划

 

int d[100010];
int n,m;
vector<int> son[100010];
int f[100010];
void toposort()
{
    int pre[100010],h=1,r=0;
    for(int i=1;i<=n;i++)
        if(d[i]==0)
            pre[++r]=i;
    while(r>=h)
    {
        int t=pre[h];
        ++h;
        for(auto y:son[t])
            if(--d[y]==0)
                pre[++r]=y;
    }   
    for(int i=n;i;--i)
    {
        int x=pre[i];
        f[x]=100;
        for(auto y : son[x])
           f[x]=max(f[x],f[y]+1);
    }
    int ans=0;
    for(int i=1;i<=n;i++)
    ans+=f[i];
    cout<<ans<<endl;
}
void solve()
{       
    cin>>n>>m;
    for(int i=1;i<=m;i++)
    {
        int x,y;    cin>>x>>y;
        son[x].push_back(y);
        d[y]++;
    }
    toposort();
    return;
}
int main()
{
    std::ios::sync_with_stdio(false);   cin.tie(nullptr), cout.tie(nullptr);
    solve();    
    return 0;
}

本文来自博客园,作者:magicat,转载请注明原文链接:https://www.cnblogs.com/magicat/p/16535093.html

posted on 2022-07-30 15:31  magicat  阅读(156)  评论(0)    收藏  举报
刷新页面返回顶部
博客园  ©  2004-2025
浙公网安备 33010602011771号 浙ICP备2021040463号-3