传送门:http://acm.hdu.edu.cn/showproblem.php?pid=4857
用map[30001][30001]肯定是会MLE的,哪怕用bool也一样,因为由于电脑寻址的原因(具体可以看看汇编原理),其实bool是一byte的内存长度(即char),而不是1bit。
所以我们用到STL中的vector(STL是真的香),之后由百度得出一个结论:要逆序输入。
原因涉及到priority_queue的用法,具体看代码。
逆序AC代码:
#include<cstring>
#include<cstdio>
#include<vector>
#include<queue>
using namespace std;
int n;
int in[30001];
vector<int> edge[30001]; //伪二维数组
priority_queue<int> q; //优先队列按从大到小排列
int main()
{
int m,t,a,b;
scanf("%d",&t);
while(t--)
{
int ans[30001],cnt=0;
memset(in,0,sizeof(in));
scanf("%d%d",&n,&m);
for(int i=1;i<=n;i++) edge[i].clear();
while(m--)
{
scanf("%d%d",&a,&b);
in[a]++; //反向建立关系
edge[b].push_back(a); //将在b前面的数存到edge[b]中
}
for(int i=1;i<=n;i++)
{
if(in[i]==0) q.push(i); //将入度为0的数找出来,放在优先队列中
}
while(!q.empty())
{
int x=q.top();
ans[++cnt]=x;//记录答案
q.pop();
for(int j=0;j<edge[x].size();j++)
{
int y=edge[x][j];
in[y]--;
if(in[y]==0) q.push(y);
}
}
for(;cnt>0;cnt--) printf("%d%c",ans[cnt],cnt==1?'\n':' ');//逆序输出
}
return 0;
}
正序代码:
#include<cstring>
#include<cstdio>
#include<vector>
#include<queue>
using namespace std;
int n;
int in[30001];
vector<int> edge[30001]; //伪二维数组
priority_queue<int, vector<int>,greater<int> > q; //优先队列按从小到大排列
int main()
{
int m,t,a,b;
scanf("%d",&t);
while(t--)
{
int ans[30001],cnt=0;
memset(in,0,sizeof(in));
scanf("%d%d",&n,&m);
for(int i=1;i<=n;i++) edge[i].clear();
while(m--)
{
scanf("%d%d",&a,&b);
in[b]++; //正向建立关系
edge[a].push_back(b);
}
for(int i=1;i<=n;i++)
{
if(in[i]==0) q.push(i); //将入度为0的数找出来,放在优先队列中
}
while(!q.empty())
{
int x=q.top();
ans[++cnt]=x;//记录答案
q.pop();
for(int j=0;j<edge[x].size();j++)
{
int y=edge[x][j];
in[y]--;
if(in[y]==0) q.push(y);
}
}
for(int i=1;i<=cnt;i++) printf("%d%c",ans[i],i==cnt?'\n':' ');//正序输出
}
return 0;
}
然鹅,正序是无法AC的,因为
对于1->4->2 5->3->2
(正序):1 4 5 3 2
(逆序):1 5 3 4 2
可以看出4和3没有直接关系,但是相对于正序,逆序的3位置更为靠前。这就是Wrong Answer的原因所在。