题解 P1347 【排序】

思路

能够将$A<B$当作$A$和$B$之间有一条权值为1有向边,那么$A-B$的值就表示为排完序后,$A$在$B$前面几位。c++

而后分状况,判断结果为第1,2,3种中的哪种。数组

判断结果为第1种的方法函数

若是有刚好有$(n-1)*n/2$条边没有被更新,说明结果确定为第1种。spa

为何呢?code

由于当能将这些变量排序时,邻接矩阵的状况必定是这个亚子的:排序

x1 x2 x3 x4 x5 ... xn
x1  0  1  2  3  4 ... n-1
x2 -1  0  1  2  3 ... n-2
x3 -1 -1  0  1  2 ... n-3
x4 -1 -1 -1  0  1 ... n-4
x5 -1 -1 -1 -1  0 ... n-5
...
xn -1 -1 -1 -1 -1 ... 0

"-1"表示A-B之间没有边,xi表示排在第i位的变量

因此没被更新的边的数量必定为$(n-1)*n/2$。ci

判断结果为第2种的方法get

若是找到两个变量$A,B$,$A$在$B$前面,$B$也在$A$前面,那么这确定矛盾了,因此结果确定为第2种。it

判断结果为第3种的方法io

若是结果不为第1,2种,那么结果确定为第3种。

代码

#include<bits/stdc++.h>
using namespace std;

int Map[30][30];
int ans[30];
int n,m,flag;
//flag=1表示结果为第1种,flag=-1表示结果为第2种,flag=0表示结果为第3种

inline void get(int &u,int &v)//获得边的信息
{
    char ch=getchar();
    while(ch>'Z'||ch<'A')
        ch=getchar();
    u=ch-'A',ch=getchar();
    while(ch>'Z'||ch<'A')
        ch=getchar();
    v=ch-'A';
}

inline void floyd(int u,int v)//将图更新
{
    for(register int i=0;i<n;i++)
        for(register int j=0;j<n;j++)
            if(Map[i][j]<Map[i][u]+1/* 1表示u,v之间有一条权值为1的单向边 */+Map[v][j])
                Map[i][j]=Map[i][u]+1+Map[v][j]; 
                //若是Map[i][j]<Map[i][u]+1+Map[v][j],说明i-j之间还有u和v,因而更新Map[i][j]的值
    //这里不用单独更新u-v,当i==u,j==v时就已经更新了
}

inline void check(int now)//判断结果为第1,2,3种中的哪种
{
    if(flag) return;
    //判断结果是否为第2种
    for(int i=0;i<n;i++)
        for(int j=0;j<n;j++)
            if(Map[i][j]>0&&Map[j][i]>0) flag=-1;
            //若是j在i前面且i在j前面,那么结果为第二种
    if(flag==-1){ans[0]=now;return;}
    //判断结果是否为第1种
    if(now<n-1) return;//若是操做序列次数<n-1确定结果不为第1种
    int tot=0,p,tf;
    //tot为有多少条边还没被更新,p为在最前面的变量,tf为当前变量是否在最前面
    for(int i=0;i<n;i++){
        tf=1;
        for(int j=0;j<n;j++)
            if(Map[i][j]<0) tot++,tf=0;
            //若是这个变量不能到达其余全部变量,那么他就不在最前面
        if(tf) p=i;
    }
    if(tot!=(n-1)*n/2) return;
    flag=1,ans[0]=now;
    //更新ans数组
    for(int i=0;i<n;i++)
        ans[Map[p][i]+1]=i;
}

inline void print()//输出函数
{
    if(flag){
        if(flag==1){
            printf("Sorted sequence determined after %d relations: ",ans[0]);
            for(int i=1;i<=n;i++) printf("%c",ans[i]+'A'); puts(".");
        }
        else printf("Inconsistency found after %d relations.\n",ans[0]);
    }
    else puts("Sorted sequence cannot be determined.");
}

int main()
{
    while(cin>>n>>m){
        //初始化
        memset(Map,-10,sizeof Map);
        for(int i=0;i<n;i++) Map[i][i]=0;
        flag=0; 
        //输入
        int u,v;
        for(int i=1;i<=m;i++){
            get(u,v);
            floyd(u,v);
            if(flag) continue;
            check(i);
        }
        //输出
        print();
    }
    return 0;
}
/*
Sorted sequence determined after () relations: ().
Inconsistency found after () relations.
Sorted sequence cannot be determined.
*/
相关文章
相关标签/搜索