AcWing 343. 排序 (Floyd, 拓扑关系,传递闭包)

🥄 🥄 🥄

Floyd做传递闭包的时候,最后生成的图中,每个点与他前面的所有点相连.
(1)指向某点的边数即为该点的rank
(2)重点在通过Floyd做闭包传递

int n,m,f[33][33];//拓扑关系
void solve()
{
    memset(f,0,sizeof(f));
    vector<string>s(m);cin>>s;
    rep(i,m)
    {
        int x=s[i][0]-'A',y=s[i][2]-'A';
        f[x][y]=f[x][x]=f[y][y]=1;//自己能到达自己,方便一会转移
        rep(j,26) rep(k,26) //闭包传递
            f[j][k]|=(f[j][x]&&f[y][k]);
        int bian=0;
        rep(j,26) rep(k,26) //检验是否成环
        {
            if(j!=k&&f[j][k]&&f[k][j])
            {
                //成环
                printf("Inconsistency found after %d relations.\n",i+1);
                return;
            }
            if(j!=k&&(f[j][k]||f[k][j])) ++bian;//两点之间存在拓扑关系
        }
        if(bian==(n-1)*n)//一共有这么多种//说明排完序
        {
            vector<int>rank(33,0);//指向该点的边数代表排名
            rep(j,26) rep(k,26) if(f[j][k]) ++rank[k];
            char ans[33];
            rep(j,26) ans[rank[j]] = j+'A';
            ans[n+1]=0;
            printf("Sorted sequence determined after %d relations: %s.\n",i+1,ans+1);
            return;
        }
    }
    printf("Sorted sequence cannot be determined.\n");
}
signed main()
{
    while(cin>>n>>m)
    {
        if(n==0&&m==0) break;
        solve();
    }
    return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值
>