【洛谷P1347】排序

题目大意:给定 N 个变量和 M 个变量之间的偏序关系,问能否求出这 N 个变量之间的一个全序。若能,输出最少利用多少条已知信息即可求的结果,且输出该全序;若无解,输出到第几条已知信息可以判定无解;若读到最后一条信息也无法判断,输出无法判断。

题解:偏序关系自然对应着一个有向图,每一个已知信息等价为给这个有向图加一条边,若能够得到全序,则证明拓扑排序过程中能够找出一条长度为 N 的链,若无解,则是在拓扑排序过程中存在自环,否则就是无法判断。

代码如下

#include <bits/stdc++.h>
using namespace std;
const int maxn=30;

vector<int> G[maxn];
char ops[10];
int n,m,idx,indeg[maxn],tmp[maxn],stk[maxn],top,d[maxn];//d[i]为以 i 结尾的最长路径
bool circle,certain;

inline void add_edge(int from,int to){G[from].push_back(to),++indeg[to];}

void topo_sort(int now){
    queue<int> q;int dep=1;//dep为当前DAG上的最长路径的长度
    for(int i=1;i<=n;i++)d[i]=0;
    for(int i=1;i<=n;i++){
        tmp[i]=indeg[i];
        if(!tmp[i])q.push(i),d[i]=1;
    }
    top=0;
    while(q.size()){
        int u=q.front();q.pop();
        stk[++top]=u;
        for(int i=0;i<G[u].size();i++){
            int v=G[u][i];--tmp[v];
            if(!tmp[v])q.push(v);
            d[v]=max(d[v],d[u]+1);
            dep=max(dep,d[v]);
        }
    }
    if(top^n)circle=1,idx=now;
    else if(dep==n)certain=1,idx=now;
}

void solve(){
    for(int i=1;i<=m;i++){
        scanf("%s",ops+1);
        if(circle||certain)break;
        int from=ops[1]-'A'+1,to=ops[3]-'A'+1;
        add_edge(from,to);
        topo_sort(i);
    }
    if(certain){
        printf("Sorted sequence determined after %d relations: ",idx);
        for(int i=1;i<=n;i++)printf("%c",stk[i]+'A'-1);
        printf(".\n");
    }
    else if(circle)printf("Inconsistency found after %d relations.\n",idx);
    else printf("Sorted sequence cannot be determined.\n");
}

int main(){
    scanf("%d%d",&n,&m);
    solve();
    return 0;
}

转载于:https://www.cnblogs.com/wzj-xhjbk/p/9932184.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值