链接:http://poj.org/problem?id=1094
题意&思路:直接拓扑排序。多解输出一串英文,有环输出一段英文,唯一解输出一段英文及排序结果。
细节:题目描述不是很清楚,如果不看discuss我肯定要WA出翔。
discuss里总结了两点关键的:
1. 输入一条边时如果此时拓扑有解就输出这个解,即使后面的边成有向环也不管了,所以每次输入的时候都得进行拓扑排序。
2. 判断存在有向环应先于判断多解。
这道题主要是题目坑爹。
#include<cstring>
#include<string>
#include<fstream>
#include<iostream>
#include<iomanip>
#include<cstdio>
#include<cctype>
#include<algorithm>
#include<queue>
#include<map>
#include<set>
#include<vector>
#include<stack>
#include<ctime>
#include<cstdlib>
#include<functional>
#include<cmath>
using namespace std;
#define PI acos(-1.0)
#define MAXN 50100
#define eps 1e-7
#define INF 0x7FFFFFFF
#define LLINF 0x7FFFFFFFFFFFFFFF
#define seed 131
#define MOD 1000000007
#define ll long long
#define ull unsigned ll
#define lson l,m,rt<<1
#define rson m+1,r,rt<<1|1
struct node{
int u,v,next;
}edge[MAXN];
int head[30],in[30],ans[30],IN[30];
int n,m,cnt,sum;
void add_edge(int a,int b){
edge[cnt].u = a;
edge[cnt].v = b;
edge[cnt].next = head[a];
head[a] = cnt++;
}
int toposort(){
int i;
for(i=0;i<n;i++){
in[i] = IN[i];
}
queue<int>q;
for(i=0;i<n;i++){
if(!in[i]) q.push(i);
}
sum = 0;
int flag = 0;
if(q.size()>1) flag = 1;
while(!q.empty()){
int u = q.front();
q.pop();
ans[sum] = u;
sum++;
for(i=head[u];i!=-1;i=edge[i].next){
int next = edge[i].v;
in[next]--;
if(in[next] == 0) q.push(next);
}
if(q.size()>1) flag = 1;
}
if(sum!=n) return 2;
else if(flag) return 1;
return 3;
}
int main(){
int i,j;
char str[5];
while(scanf("%d%d",&n,&m),n||m){
memset(IN,0,sizeof(in));
memset(head,-1,sizeof(head));
int flag = 0;
cnt = 0;
int temp;
int p;
for(i=0;i<m;i++){
scanf("%s",str);
// cout<<str<<endl;
if(flag) continue;
IN[str[2]-'A']++;
add_edge(str[0]-'A',str[2]-'A');
temp = toposort();
if(temp==3||temp==2){
flag = 1;
p = i + 1;
}
}
if(flag){
if(temp==3){
printf("Sorted sequence determined after %d relations: ",p);
for(i=0;i<n;i++){
printf("%c",ans[i]+'A');
}
printf(".\n");
}
else if(temp==2){
printf("Inconsistency found after %d relations.\n",p);
}
}
else printf("Sorted sequence cannot be determined.\n");
}
return 0;
}