题目大意:略。
解题思路: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(""); }