ZOJ1060

来源:互联网 发布:04年总决赛科比数据 编辑:程序博客网 时间:2024/05/21 19:33

题目链接:http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemId=60

很明显是拓扑排序,但是以前学的拓扑排序有漏洞,不能做这道题,所以看了解析,提供了另一种拓扑排序的方法,可以返回三种信息:排序成功、关系矛盾、关系不确定。

这个方法,强化记忆吧。

#include<cstdio>const int MAXN = 30;int data[MAXN][MAXN];int sorted[MAXN];int n, m;int topologic(int left[], int right[], int used[]){    int judge[MAXN];    int sameLayer[MAXN];    int count = 0;    int order = 1;    int i, j;    for (i=1; i<MAXN; i++)    {        judge[i] = right[i];        if (!used[i])            judge[i] = -1;    }    while (true)    {        int total = 0;        i = 1;        while (i <= n)        {            while ((i <= n) && (judge[i] != 0)) i++;            if (i > n)                break;            sameLayer[++total] = i;            judge[i] = -1;            sorted[++count] = i;        }        if (total == 0)            break;        if (total > 1)            order = 0;        for (j=1; j<=total; j++)        {            i = sameLayer[j];            for (int k=1; k<=left[i]; k++)                judge[data[i][k]]--;        }    }    if (count == n)    {        if (!order)            return -1;        return 0;    }    if (count < n)    {        for (i=1; i<=n; i++)            if (judge[i] > 0)                return 1;        return -1;    }}int main(){    int relation[MAXN * MAXN][2];    int right[MAXN], left[MAXN];    int used[MAXN];    while (scanf("%d%d\n",&n,&m) && n)    {        for (int i=0; i<MAXN; i++)            left[i] = right[i] = used[i] = sorted[i] = 0;        char three[10];        for (int i=0; i<m; i++)        {            scanf("%s",three);            relation[i][0] = three[0] - 'A' + 1;            relation[i][1] = three[2] - 'A' + 1;        }        int result = 0;        for (int i=0; i<m; i++)        {            int x = relation[i][0];            int y = relation[i][1];            data[x][++left[x]] = y;            ++right[y];            used[x] = 1;            used[y] = 1;            int flag = topologic(left, right, used);            if (flag == 0)            {                printf("Sorted sequence determined after %d relations: ",i+1);                for (int j=1; j<=n; j++)                    printf("%c",(char)(sorted[j]+64));                printf(".\n");                result = 1;                break;            }            if (flag == 1)            {                printf("Inconsistency found after %d relations.\n",i+1);                result = 1;                break;            }        }        if (!result)            printf("Sorted sequence cannot be determined.\n");    }    return 0;}
拓扑排序模板:

#include<iostream>#include<memory.h>#define MAXN 500using namespace std;int data[MAXN][MAXN];int sorted[MAXN];int n, m;int topologic(int left[], int right[], bool used[]){    int judge[MAXN];    int sameLayer[MAXN];    int count = 0;    bool order = true;    int i, j;    for (i=1; i<MAXN; i++)    {        judge[i] = right[i];        if (!used[i])            judge[i] = -1;    }    while (true)    {        int total = 0;        i = 1;        while (i <= n)        {            while (i <=n  && judge[i] != 0) i++;            if (i > n)                break;            sameLayer[++total] = i;            judge[i] = -1;            sorted[++count] = i;        }        if (total == 0)            break;        if (total > 1)            order = false;        for (j=1; j<=total; j++)        {            i = sameLayer[j];            for (int k=1; k<=left[i]; k++)                judge[data[i][k]]--;        }    }    if (count == n)    {        if (!order)            return -1;        return 0;    }    if (count < n)    {        for (i=1; i<=n; i++)            if (judge[i] > 0)                return 1;        return -1;    }}int main(){    int right[MAXN], left[MAXN]; //入度和出度    bool used[MAXN];    memset(right,0,sizeof(right));    memset(left,0,sizeof(left));    memset(used,false,sizeof(used));    cin>>n>>m;    for (int i=0; i<m; i++)    {        int x, y;        cin>>x>>y;        data[x][++left[x]] = y;        ++right[y];        used[x] = true;        used[y] = true;    }    int flag = topologic(left, right, used);    switch (flag)    {        case -1:cout<<"无法判断关系!"<<endl; break;        case 1:cout<<"关系矛盾!"<<endl; break;        default:            {                cout<<"拓扑排序的结果如下:"<<endl;                for (int i=1; i<=n; i++)                    cout<<sorted[i]<<' ';                cout<<endl;            }    }    return 0;}



0 0
原创粉丝点击