题目:http://poj.org/problem?id=1094
Sorting It All Out
Time Limit: 1000MS | | Memory Limit: 10000K |
Total Submissions: 30357 | | Accepted: 10518 |
Description
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.
Input
Input consists of multiple problem instances. Each instance starts with a line containing two positive integers n and m. the first value indicated the number of objects to sort, where 2 <= n <= 26. The objects to be sorted will be the first n characters of the uppercase alphabet. The second value m indicates the number of relations of the form A < B which will be given in this problem instance. Next will be m lines, each containing one such relation consisting of three characters: an uppercase letter, the character "<" and a second uppercase letter. No letter will be outside the range of the first n letters of the alphabet. Values of n = m = 0 indicate end of input.
Output
For each problem instance, output consists of one line. This line should be one of the following three:
Sorted sequence determined after xxx relations: yyy...y.
Sorted sequence cannot be determined.
Inconsistency found after xxx relations.
where xxx is the number of relations processed at the time either a sorted sequence is determined or an inconsistency is found, whichever comes first, and yyy...y is the sorted, ascending sequence.
Sample Input
4 6 A<B A<C B<C C<D B<D A<B 3 2 A<B B<A 26 1 A<Z 0 0
Sample Output
Sorted sequence determined after 4 relations: ABCD. Inconsistency found after 2 relations. Sorted sequence cannot be determined.
分析:很经典的拓扑排序。矛盾关系的产生(Inconsistency found after xxx relations. )是因为在有向图中产生了环;大小关系的确定(Sorted sequence determined after xxx relations: yyy...y. )是整个有向图的拓扑排序已经完成;无法确定整个序列的单调关系(Sorted sequence cannot be determined. )则是m条有向边建立完了后仍然没有前两者的判断结果。完成它确实不容易,TLE了4次,WA了4次,前者是因为没有搞懂"after xxx relations."这句话的内涵,需要每次建立新边后立即判断一下有没有环,完没完成拓扑排序,如果判断了则输出结果,后面只需要输入剩下的关系就可以了,如果m条有向边建立完成了都没有前两个的判断结果,那么就是无法确定结果。WA的原因我是真没看出来,后来换了一种写法(模仿||-_-)才过的。
为逝去的代码默哀三分钟:WA
#include <iostream>
#include <cstdio>
#include <cstring>
using namespace std;
int head[30],indeg[30],n,m,sum;
struct node{
int to,next;
}edge[30];
bool vis[30];
void init(){
sum=0;
memset(vis,0,sizeof(vis));
memset(indeg,0,sizeof(indeg));
memset(head,-1,sizeof(head));
memset(edge,0,sizeof(edge));
}
void addedge(int u,int v){
vis[u]=vis[v]=1;
edge[sum].to=v;
edge[sum].next=head[u];
head[u]=sum++;
indeg[v]++;
}
int report(){
int res=0;
for(int i=0;i<n;i++){
if(vis[i]) res++;
}
return res;
}
int que[30],top;
int topo(){ // 1: not determined 2: inconsistent 有环矛盾 3: OK
top=0;
int ing[30],all=report();
for(int i=0;i<n;i++) ing[i]=indeg[i];
for(int i=0;i<n;i++){
if(ing[i]==0&&vis[i]){ que[top++]=i; ing[i]--; } //printf("%c\n",i+'A');
}
if(top==0) return 2; //大环
for(int i=0;i<top;i++){
for(int j=head[que[i]];j>-1;j=edge[j].next){
ing[edge[j].to]--;
if(ing[edge[j].to]==0&&vis[j]){
que[top++]=edge[j].to;
ing[edge[j].to]--;
}
}
}
if(top==n) return 3;
if(top<all) return 2; //小环
return 0;
}
int main()
{
//freopen("cin.txt","r",stdin);
char str[5];
int flag;
while(cin>>n>>m&&(n+m)){
init();
flag=0;
for(int i=0;i<m;i++){
scanf("%s",str);
if(flag) continue;
addedge(str[0]-'A',str[2]-'A');
flag=topo();
if(flag){
if(flag==3) {
printf("Sorted sequence determined after %d relations: ",i+1);
for(int j=0;j<n;j++){ printf("%c",que[j]+'A'); }
puts(".");
}
else if(flag==2)printf("Inconsistency found after %d relations.\n",i+1);
}
}
if(!flag) puts("Sorted sequence cannot be determined.");
}
return 0;
}
接下来是正确的:
#include <iostream>
#include <cstdio>
#include <cstring>
using namespace std;
int n,m,sum;
int map[30][30],indeg[30],que[30],top;
int topo(){ // 1:OK 2: 有环,矛盾 3:not sure
int ing[30],loc,flag=1;
top=0;
for(int i=0;i<n;i++) ing[i]=indeg[i];
for(int i=0;i<n;i++){
int sum=0;
for(int j=0;j<n;j++){
if(ing[j]==0){ sum++; loc=j; } //把"ing[loc]--;"放在这里面会
} //提前让两个剩余的点由0变-1,进而得到sum==0的后果
if(sum==0) return 2;
if(sum>1) flag=3;
que[top++]=loc;
ing[loc]--;
for(int j=0;j<n;j++)
if(map[loc][j]) ing[j]--;
}
return flag;
}
int main()
{
//freopen("cin.txt","r",stdin);
char str[5];
while(cin>>n>>m&&(n+m)){
memset(map,0,sizeof(map));
memset(indeg,0,sizeof(indeg));
bool tag=0;
for(int i=0;i<m;i++){
scanf("%s",str);
if(tag) continue;
int x=str[0]-'A',y=str[2]-'A';
map[x][y]=1;
indeg[y]++;
int p=topo();
if(p==2){
printf("Inconsistency found after %d relations.\n",i+1);
tag=1;
}
else if(p==1){
printf("Sorted sequence determined after %d relations: ",i+1);
for(int j=0;j<n;j++) printf("%c",que[j]+'A');
puts(".");
tag=1;
}
}
if(!tag) puts("Sorted sequence cannot be determined.");
}
return 0;
}