题目:http://poj.org/problem?id=1094
Time Limit: 1000MS | Memory Limit: 10000K | |
Total Submissions: 30357 | Accepted: 10518 |
Description
Input
Output
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的原因我是真没看出来,后来换了一种写法(模仿||-_-)才过的。
#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; }