【竞赛之路】(poj 1094) 变量排序

来源:互联网 发布:同志聊天室软件 编辑:程序博客网 时间:2024/04/29 16:07
【问题描述】  
  把不同的变量进行升序排序用小于操作符命令实现的。例如由A < B, B < C 和 C < D 可以得到升序序列A, B, C, D 。

  在本题中,你将得到若干条小于操作符命令,形如 A < B 的格式,请你确定利用这些命令,能否得到一个唯一的升序序列。    【输入格式】  
  第1行为整数n,m,n(2 <= n <= 26)表示参与排序的是前n个大写字母,m表示给出命令的条数。    【输出格式】  
  输出一行:
  如果根据输入能得到唯一的升序序列,则输出“Sorted sequence determined after xxx relations: yyy...y. ”
  如果不能得到唯一的升序序列,则输出“Sorted sequence cannot be determined. ”
  如果不能得到升序序列,则输出“Inconsistency found after xxx relations. ”
  上面的信息中 xxx 是一个整数,是表示至多根据前xxx条信息就可以得出该结论。 yyy...y表示得到的升序序列的大写字母串。    【输入样例】  
【样例1】
 4 6
 A < B
 A < C
 B < C
 C < D
 B < D
 A < B

【样例2】
 3 2
 A < B
 B < A

【样例3】
 26 1
 A < Z    【输出样例】  
【样例1】
 Sorted sequence determined after 4 relations: ABCD.

【样例2】
 Inconsistency found after 2 relations.

【样例3】
 Sorted sequence cannot be determined.    【数据范围】  
2 <= n <= 26

今天上课讲的第二题,开始做的时候还是有一点懵逼的,最先觉得要用传递闭包来解决的,但是,想了一下每次加条边都要O(n^3)这样的代价,呵呵。

但是本题的本质还是一个排序题,而且已知条件给出的是变量之间的大小关系(图的边),这不得不让人想到DAG图和拓补排序。

所以这个题的思路是:循环题目给出的信息,将每一个变量看作是DAG图的一个顶点,利用题目给出的大小关系,建立一个DAG图,并用BFS(或者DFS)对这个图进行拓补

排序,如果排序失败(也就是图有环,不是一个DAG)的话,显然就是第三种情况了,而排序成功的话,有两种情况:

1.有唯一的拓补序列;       2.拓补序列不唯一.

我们知道,拓补序列实质是一个满足DAG图的特殊的组合,所以要判断该组合是否唯一,就要看拓补排序中选择时选择个数是否唯一,所以只需在BFS时判断队列中是否

有两个以上的元素,如果有则说明是第二种情况(也就是排序过程中存在两种及以上种选择 因为在有多个元素时先选元素1和元素2都可以得到一个拓补序列,会使解不唯一)

否则则是情况1.

所以主算法框架为每读入一条信息进行一次排序,然后按照上面的规则判断并输出结果.

这个题有三个坑爹的地方,一个是不唯一情况的判定需要考察m个信息,因为信息少于m条时可能是无解的情况,但加上几条边又有解了.

第二是在判断终端节点时不能改变原来的出度入度数组

第三个是不能直接以(q.size()>1)就直接判断2,因为2是建立在有解的大前提下的,而q.size()>1时遍历到后面也可能无解

附上代码(刚刚手贱误删了望见谅)

#include<cstdio>#include<iostream>#include<cstring>#include<queue>#include<vector>using namespace std;const int maxn=35;vector<int>g[maxn];int n,m;int rd[maxn],trd[maxn];char str[5];vector<int>topo;int BFS(){queue<int>q;memcpy(trd,rd,sizeof(rd));topo.clear();for(int i=1;i<=n;i++)if(trd[i]==0)q.push(i);int flag=0;while(!q.empty()){if(q.size()>1)flag=2;int i=q.front();q.pop();topo.push_back(i);for(int k=0;k<g[i].size();k++){int j=g[i][k];if(trd[j]>0)trd[j]--;if(trd[j]==0)q.push(j);}}if(topo.size()<n)return 0;if(flag==2)return 2;return 1;}int main(){//freopen("my.in","r",stdin);//freopen("my.out","w",stdout);scanf("%d%d",&n,&m);for(int i=1;i<=m;i++){scanf("%s",str);int x,y;x=str[0]-'A'+1;y=str[2]-'A'+1;g[x].push_back(y);rd[y]++;int t=BFS();if(t==0){printf("Inconsistency found after %d relations.",i);break;}else if(t==1){printf("Sorted sequence determined after %d relations: ",i);for(int k=0;k<topo.size();k++)printf("%c",topo[k]+'A'-1);printf(".");break;}else if(i==m && t==2){printf("Sorted sequence cannot be determined.");break;}}return 0;}


 

0 0
原创粉丝点击