2237: Hero Ranklist
Result | TIME Limit | MEMORY Limit | Run Times | AC Times | JUDGE |
---|---|---|---|---|---|
5s | 8192K | 257 | 119 | Standard |
Arthur想要将手下的战士按照能力进行排名, 选择出得力的助手进行冒险. 他收集了很多人之间比武的胜负情况,如A战胜了B,B战胜了C等。他发现,这些胜负关系之间彼此互不矛盾,也就是不能出现C又战胜了A这种情况,但很多人之间并没有比武, 也就无法衡量谁更强。在这种情况下,Arthur想把所有可能的排行榜都列举出来,供他进一步研究。
本题目包括多个Case。每个Case的第一行有2个数字m,n. m<13,代表有多少个人物,每个人物使用一个大写字母表示。之后有n行, n<100, 每一行有2个字母X Y, 中间有一个减号, 表示X战胜过Y。可以假定输入没有重复.
3 2 A-B A-C 4 3 A-B C-A C-D
ABC ACB CABD CADB CDAB
Problem Source: skywind
This problem is used for contest: 32
一道拓扑排序的题,数据结构上老师讲的有点不同,这个要求是输出全部的可能,借鉴了又岸的一些方法,在这里感谢一下!
思路:
拓扑排序的知识如果你开数据结构课了就应该知道,如果不知道的话就自己上网看看吧。
总的思想就是,每次从一个有向图中找到入度是0的顶点输出,然后把和他邻接的顶点间的边都删掉(注意这个点要作为这个边的始点才可以删这条边)这样子一直进行下去,就会得到一个拓扑排序。
这题也是一个思路,但是注意题目要求输出所有可能的拓扑排序,所以这个就要用到深搜+回溯(借鉴又岸),把所有可能都输出出来,并且是按字典序的。
这个题并没有什么特别的地方,就是单纯的数据结构的简单题目,就不多说了。
可能是用了深搜的缘故,所以用了0.27s第一的大神用了才0.05s.
Code:
<textarea cols="50" rows="15" name="code" class="c-sharp">/* *JackyZheng *2010/12/14 *C */ #include<stdio.h> #include<cstring> short n,m; short count[13]; short map[13][13]; short visited[13]; short ans[13]; void dfs(short dep) { if(dep==n) { short i; for(i=0;i<n;i++) { printf("%c",ans[i]+'A'); } printf("/n"); return; } short i; for(i=0;i<n;i++) { if(visited[i]==0&&count[i]==0) { visited[i]=1; ans[dep]=i; short j; for(j=0;j<n;j++) { if(map[i][j]) { count[j]--; } } dfs(dep+1); visited[i]=0; for(j=0;j<n;j++) { if(map[i][j]) { count[j]++; } } } } } int main() { char str[4]; while(scanf("%d%d",&n,&m)!=EOF) { memset(count,0,sizeof(count)); memset(map,0,sizeof(map)); memset(visited,0,sizeof(visited)); short i; for(i=0;i<m;i++) { scanf("%s",str); map[str[0]-'A'][str[2]-'A']=1; count[str[2]-'A']++; } dfs(0); printf("/n"); } } </textarea>