您的位置:首页 > 其它

poj1094 拓扑排序(屎)

2016-07-27 11:10 375 查看
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;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  acm 拓扑排序