0
点赞
收藏
分享

微信扫一扫

ZCMU - 2153: D.ly的排队问题


题目链接:​​点击打开链接​​

题目大意:略。

解题思路: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("");
}


举报

相关推荐

0 条评论