试题
有N个士兵(1≤N≤26),编号依次为A,B,C,…,队列训练时,指挥官要把一些士兵从高到矮一次排成一行,但现在指挥官不能直接获得每个人的身高信息,只能获得“P1比P2高”这样的比较结果(P1、P2∈A,B,C,…,Z,记为 P1>P2),如”A>B”表示A比B高。
请编一程序,根据所得到的比较结果求出一种符合条件的排队方案。
(注:比较结果中没有涉及的士兵不参加排队)
请编一程序,根据所得到的比较结果求出一种符合条件的排队方案。
(注:比较结果中没有涉及的士兵不参加排队)
输入要求
比较结果从文本文件中读入(文件由键盘输入),每个比较结果在文本文件中占一行。
输出要求
若输入数据无解,打印“No Answer!”信息,否则从高到矮一次输出每一个士兵的编号,中间无分割符,并把结果写入文本文件中,文件由键盘输入:
样例输入
A>B
B>D
F>D
B>D
F>D
样例输出
AFBD
#include<cstdio>
#include<cstring>
#include<queue>
#include<algorithm>
#define bug(x) printf("%d***\n",x)
#define ls(x) (x<<1)
#define rs(x) (x<<1|1)
using namespace std;
typedef long long ll;
const int maxn=30;
int indegree[maxn];
int vis[maxn],mp[30][30];
char ans[maxn];
int cnt;
int head[400];
struct Edge{
int v,nt;
}edge[400];
void add_edge(int u,int v){
edge[cnt].nt=head[u];
edge[cnt].v=v;
head[u]=cnt++;
}
queue<int> q;
int num;
void topsort(){
for(int i=0;i<26;i++){
if(vis[i]&&!indegree[i]){
vis[i]=0;
q.push(i);//不能找到一个点,就直接跳出的话不可以,有可能不是联通图
}
}
while(!q.empty()){
int now=q.front();
q.pop();
vis[now]=0;
ans[num++]=now+'A';
for(int i=head[now];i!=-1;i=edge[i].nt){
int v=edge[i].v;
indegree[v]--;
if(indegree[v]==0&&vis[v]){
q.push(v);
}
}
}
}
char str[10];
int main(){
cnt=0;
int n=0;
memset(head,-1,sizeof(head));
while(gets(str)){
if(str[0]==EOF) break;
int a=str[0]-'A',b=str[2]-'A';
if(!vis[a]){
vis[a]=1;n++;
}
if(!vis[b]){
vis[b]=1;n++;
}
if(str[1]=='>'){//如果重复输入的话,不要再添加
indegree[a]++;
add_edge(b,a);
}
else {
indegree[b]++;
add_edge(a,b);
}
}
num=0;
topsort();
if(num<n)
printf("No Answer!\n");
else{
for(int i=n-1;i>=0;i--)
printf("%c",ans[i]);
printf("\n");
}
return 0;
}