题目链接:点击打开链接
题目大意:略。
解题思路:Topo排序 + 优先队列。
AC 代码
#include<bits/stdc++.h>
#include<cmath>
#define mem(a,b) memset(a,b,sizeof a)
using namespace std;
typedef long long ll;
const int MAXV=1010;
int vis[MAXV];
int mp[MAXV][MAXV]; // 邻接矩阵边连结
int in[MAXV]; // 入度
char rcd[MAXV]; // 最终记录
int n,len; // 顶点个数 最终记录长度
struct node
{
int top;
char ch;
};
node nds[MAXV];
struct pq_cmp
{
bool operator()(node nd1,node nd2)
{
return nd1.ch>nd2.ch; // 字母字典序
}
};
priority_queue<node,vector<node>,pq_cmp> pq;
void init()
{
mem(vis,0);
mem(mp,0);
mem(in,0);
mem(rcd,'\0');
len=n=0;
while(!pq.empty()) pq.pop();
}
int TopoSort()
{
// int top=-1;
node ndtop; // 临时变量,类似 top 变量
ndtop.top=-1;
for(int i=1;i<=n;i++)
{
if(in[i]==0)
{
// in[i]=top;
// top=i;
in[i]=ndtop.top;
ndtop.top=i;
nds[i].top=i;
pq.push(nds[i]); // 数据加完后再在下面 if语句 取出,下面内层 for_k 当中也同理可得
}
}
if(!pq.empty())
{
ndtop=pq.top();
pq.pop(); // 注意每取一次,pop下
}
for(int i=1;i<=n;i++)
{
if(ndtop.top==-1)
{
// printf("No Answer!");
return 0;
}
else
{
int j=ndtop.top;
ndtop.top=in[j]; // 因为这里的 ndtop 上面保存在 j 里就没用了,所以这里可以替换新的数据
// printf("%c",crr[j]);
rcd[len++]=nds[j].ch;
for(int k=1;k<=n;k++)
{
if(mp[j][k] && --in[k]==0)
{
// in[k]=top;
// top=k;
in[k]=ndtop.top;
ndtop.top=k;
nds[k].top=k;
pq.push(nds[k]);
}
}
if(!pq.empty())
{
ndtop=pq.top();
pq.pop();
}
}
}
return 1;
}
int main()
{
init();
string s;
while(cin>>s) // while(~scanf("%c>%c",&c1,&c2)) 多组数据时,没办法 Ctrl+Z
{
int from=s[0]-'A',to=s[2]-'A';
if(vis[from]==0)
{
nds[++n].ch=s[0];
vis[from]=n;
from=n;
}
else
{
from=vis[from];
// in[from]++; // 因为from指向to,所以并不是from的入度++
}
if(vis[to]==0)
{
nds[++n].ch=s[2];
vis[to]=n;
in[n]++;
to=n;
}
else
{
to=vis[to];
// 避免重复导致 in[to]++,一般情况topo题型很喜欢有重复数据
if(mp[from][to]==1) continue;
in[to]++;
}
mp[from][to]=1;
}
if(TopoSort())
{
for(int i=0;i<len;i++)
printf("%c",rcd[i]);
}
else
printf("No Answer!");
puts("");
}