poj1094 拓扑排序(屎)

An ascending sorted sequence of distinct values is one in which some form of a less-than operator is used to order the elements from smallest to largest. For example, the sorted sequence A, B, C, D implies that A < B, B < C and C < D. in this problem, we will give you a set of relations of the form A < B and ask you to determine whether a sorted order has been specified or not.

真是一道屎题。每次加入边都需要进行一次拓扑排序看看是否能满足条件。

判断环的方法是进行n次入队,每次只入队一个点,如果某次入队时发现没有入度为零的点了,证明有环。

判断是否排序唯一的方法是每次入队看是否有多个入度为零的点,如果有证明排序不唯一

因为每次加边都需要进行一次排序,所以开始的排序一定不唯一,所以用flag保存不唯一的可能性,当m次边全部进入后再判断是否不唯一。

屎题,绝妙屎题。

代码:

#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
#include<queue>
using namespace std;
typedef long long ll;
int mpo[50][50];
int mp[50][50];
int ru[50];
int ruo[50];
bool vis[50];
vector<int> ans;
queue<int> q;
int judge(int n)
{
    while(!q.empty()) q.pop();
    memcpy(mp,mpo,sizeof(mpo));
    memcpy(ru,ruo,sizeof(ruo));
    ans.clear();
    int cnt=0;
    int flag=0;
    /*for(int i=0; i<n; i++)
    {
        if(!ru[i])
        {
            if(cnt==0)
                q.push(i);
            cnt++;
        }
    }
    printf("cnt=%d\n",cnt);
    if(cnt==0)
    {
        flag=1;    //1: have circle
        return flag;
    }
    if(cnt>1) flag=3; //3: can't determined*/
    for(int i=0; i<n; i++)
    {
        for(int i=0; i<n; i++)
        {
            if(!ru[i])
            {
                if(cnt==0)
                    q.push(i);
                cnt++;
            }
        }
        //printf("cnt=%d\n",cnt);
        if(cnt==0)
        {
            flag=1;    //1: have circle
            return flag;
        }
        if(cnt>1) flag=3; //3: can't determined
        cnt=0;
        int t=q.front();
        q.pop();
        ans.push_back(t);
        ru[t]=-1;
        for(int i=0; i<n; i++)
        {
            if(mp[t][i])
            {
                ru[i]--;
            }
        }

    }
    if(ans.size()==n&&flag!=3)
    {
        return 2;
    }
    else
        return 3;
}
char s[10];
int main()
{
    char x,y;
    int m,n,f;
    while(scanf("%d %d\n",&n,&m)!=EOF&&(m||n))
    {
        int cnt=0;
        f=0;
        //int vif=0;
        //memset(vis,0,sizeof(vis));
        memset(mpo,0,sizeof(mp));
        memset(ruo,0,sizeof(ru));
        for(int i=1; i<=m; i++)
        {
            scanf("%s",s);
            x=s[0],y=s[2];
            if(f==1||f==2) continue;
            /*if(!vis[x-'A'])
            {
            	vis[x-'A']=1;
            	vif++;
            }
            if(!vis[y-'A'])
            {
            	vis[y-'A']=1;
            	vif++;
            }*/
            mpo[x-'A'][y-'A']=1;
            ++ruo[y-'A'];
            // if(vif==n)
            f=judge(n);
            if(f==2)
            {
                printf("Sorted sequence determined after %d relations: ",i);
                for(int i=0; i<n; i++)
                    printf("%c",ans[i]+'A');
                printf(".\n");
            }
            else if(f==1)
            {
                printf("Inconsistency found after %d relations.\n",i);
            }
        }
        if(f==3)
            printf("Sorted sequence cannot be determined.\n");
    }
    return 0;
}

在验证了自己方式的正确性后又得出了另一种做法,

还是按照上一篇拓扑排序的做法,判是否有多解的方法相同,判环的方式就是最后看ans是否是n个,如果不是即为环

#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
#include<queue>
using namespace std;
typedef long long ll;
int mp[50][50];
int ru[50];
int ruo[50];
vector<int> ans;
queue<int> q;
int judge(int n)
{
    while(!q.empty()) q.pop();
    memcpy(ru,ruo,sizeof(ruo));
    ans.clear();
    int cnt=0;
    int flag=0;
    cnt=0;
    for(int i=0; i<n; i++)
    {
        if(!ru[i])
        {
            //if(cnt==0)
                q.push(i);
            cnt++;
        }
    }
    if(cnt==0)
    {
        flag=1;    //1: have circle
        return flag;
    }
    if(cnt>1) flag=3; //3: can't determined
    while(!q.empty())
    {
    	cnt=0;
    	int t=q.front();
    	q.pop();
    	ans.push_back(t);
    	for(int j=0;j<n;j++)
    	{
    		if(mp[t][j])
    		{
    			--ru[j];
				if(ru[j]==0)
				{
					q.push(j);
					cnt++;
				}
    		}
    	}
    	if(cnt>1) flag=3; //3: can't determined
    }
    if(ans.size()<n) return 1;
    if(ans.size()==n&&flag!=3)
    {
        return 2;
    }
    else
        return 3;
}
char s[10];
int main()
{
    char x,y;
    int m,n,f;
    while(scanf("%d %d\n",&n,&m)!=EOF&&(m||n))
    {
        int cnt=0;
        f=0;
        //memset(vis,0,sizeof(vis));
        memset(mp,0,sizeof(mp));
        memset(ruo,0,sizeof(ru));
        for(int i=1; i<=m; i++)
        {
            scanf("%s",s);
            x=s[0],y=s[2];
            if(f==1||f==2) continue;
            mp[x-'A'][y-'A']=1;
            ++ruo[y-'A'];
            f=judge(n);
            if(f==2)
            {
                printf("Sorted sequence determined after %d relations: ",i);
                for(int i=0; i<n; i++)
                    printf("%c",ans[i]+'A');
                printf(".\n");
            }
            else if(f==1)
            {
                printf("Inconsistency found after %d relations.\n",i);
            }
        }
        if(f==3)
            printf("Sorted sequence cannot be determined.\n");
    }
    return 0;
}


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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值