您的位置:首页 > 其它

poj1094 Sorting It All Out

2013-11-21 21:28 330 查看
链接:http://poj.org/problem?id=1094 
题意:题目的意思很简单。就是给定一些字母之间的先后关系,然后对其排序。 排序的结果有三种:一、唯一的序列;二、存在矛盾(即有环);三、无法确定序列。总的来说是这三种,但每种又有好多种情况!!!这个是本题的难点,要把所有的情况都搞清楚。然后我说一下具体的情况:1、序列唯一。如果在输入了w条边后,序列已确定,即包含了所有前n个顶点,即便后面有矛盾,序列依旧确定;2、存在矛盾,即有环存在。如果既有多个无前驱节点(即无法确定排序)又有环,则先输出矛盾。3、无法确定序列。如果输入的字母大于了最后第n个字母,则排序无法确定。如果最终输入的最大的字母任然小于第n个字母,则无法排序。如果排序完毕,无矛盾,但是字母数量没达到n个,则无法确定排序。如果一个图的子图存在多个无前驱节点,则也无法确定排序(前提是图中无矛盾)。
这个题的图是随着边条数的增加不断更新的,然后边做判断。

#include<iostream>
using namespace std;
#define  MAXN 2500
struct Edge
{
int l,r;
}edge[MAXN];
int relate[30][30];
char sans[30];  //ans再改为sans后,就能输出ABCD了
int flag;
int all_edge_num,edge_num,lett_num,rela_num;
void  Topo_Sort()
{
int i,j,u,zeroflag=0,count=1,temp_lett_num=0,zerodegree_num=0;
int into[30];
flag=1;
for(i=1;i<=lett_num;i++)
into[i]=-2;
memset(sans,'0',sizeof(sans));
for(i=1;i<=edge_num;i++)
{
into[edge[i].l]=0;
into[edge[i].r]=0;
}
for(i=1;i<=lett_num;i++)
if(into[i]==0)
temp_lett_num++;
for(i=1;i<=edge_num;i++)
if(relate[edge[i].l][edge[i].r]>0)
into[edge[i].r]++;
for(i=1;i<=lett_num;i++)
if(into[i]==0)
zerodegree_num++; //入度为0的点的个数
if(zerodegree_num==0)
{
flag=0;
return;
}
if(zerodegree_num>1)zeroflag=1;
for(i=1;i<=temp_lett_num;i++)
{
j=0;
u=1;
while(into[u]!=0)
{

if(into[u]==-1)j++;
u++;
if(j>temp_lett_num||u>lett_num)
{
flag=0;
return;
}
}
sans[count++]=u+64;
into[u]=-1;
if(count==lett_num+1&&zerodegree_num==1)
return ;
for(int k=1;k<=edge_num;k++)
{
if(edge[k].l==u)
into[edge[k].r]--;
}
if(!zeroflag)
{
zerodegree_num=0;
for(int t=1;t<=lett_num;t++)
if(into[t]==0)
zerodegree_num++;
if(zerodegree_num>1)
zeroflag=1;
}
}
if((count<lett_num+1||zerodegree_num>1)&&(edge_num==all_edge_num))
{

flag=-1;return;
}
flag=-2;
return ;
}
int main()
{
int n,m,max1,max2,signal,conflict;
int i;
char a,b,c;
while(cin>>n>>m)
{
if(n==0&&m==0)return 0;
lett_num=n;
all_edge_num=m;
conflict=0;
max2=0;
signal=0;
memset(relate,0,sizeof(relate));
for(i=1;i<=m;i++)
{
cin>>a>>c>>b;
edge[i].l=a-64;
edge[i].r=b-64;
max1=(edge[i].l>edge[i].r)?edge[i].l:edge[i].r;
if(max1>n&&!signal)
{
conflict=1;
signal=1;
rela_num=i;
}
}
if(conflict)
{
cout<<"Inconsistency found after "<<rela_num<<" relations."<<endl;
continue;
}
for(i=1;i<=m;i++)
{
relate[edge[i].l][edge[i].r]=1;
max1=(edge[i].l>edge[i].r)?edge[i].l:edge[i].r;
if(max1>max2)
max2=max1;
edge_num=i;
rela_num=i;
Topo_Sort();
if(flag==1)
{
cout<<"Sorted sequence determined after "<<rela_num<<" relations: ";
for(int t=1;t<=n;t++)
cout<<sans[t];
cout<<"."<<endl;
break;
}
if(flag==0)
{
cout<<"Inconsistency found after "<<rela_num<<" relations."<<endl;
break;
}
if(flag==-1)
{
cout<<"Sorted sequence cannot be determined."<<endl;
break;
}
if(i==m&&max2<n)
{

cout<<"Sorted sequence cannot be determined."<<endl;
break;
}
}

}
return 0;
}


 
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  poj