#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<queue>
#include<stack>
using namespace std;
int map[1000][1000];
int str[1000];
/* 起先我这个变量是rank[]的,在不是用队列的时候是可以通过的,不过
我改成用队列的方法的时候就不可以通过了,不知道是哪里错了,hdu上提示,
rank这个变量定义模糊
*/
priority_queue<int,vector<int>,greater<int> > q; //此处是优先队列的
int topo(int n,int m)
{
int i,j;
int t;
int temp;
t=n;
for(i=1;i<=n;i++)
{
if(str[i]==0)
{
q.push(i);
}
}
while(!q.empty())
{
temp=q.top();
if(t==n)// 输出格式注意
printf("%d",temp);
else
printf(" %d",temp);
q.pop();
t--;
for(j=1;j<=n;j++)
{
if(map[temp][j]==1)
{
str[j]--;
if(str[j]==0)
{
q.push(j);
}
}
}
}
printf("\n");
return 0;
}
int main()
{
int i,j;
int a,b;
int n,m;
while(scanf("%d%d",&n,&m)!=EOF)
{
memset(map,0,sizeof(map));
memset(str,0,sizeof(str));
for(i=1;i<=m;i++)
{
scanf("%d%d",&a,&b);
if(map[a][b]==0)//别把这个地方漏掉了,漏掉就错
/*
给个输入的例子:
n=3 m=3
1 2
1 2
2 3
此时n等于3,m等于3,不过输入了两组1,2;但是str[b]只能加一次,所以有这个判定条件
*/
{
map[a][b]=1;
str[b]++;
}
}
topo(n,m);
}
return 0;
}
补充:
分析:
7 8 9 10 11
第一次合并:9 10 11 15
第二次合并:11 15 19
第三次合并:19 26
第四次合并:45
我们知道最后的总长度是45
结果总和为:45+26+19+15
那么我们可以先来随便举个例子:
第一次将45分解为:15 30
第二次将: 7 8 11 19
第三次将: 9 10
所以结果总和为:15+30+19+45
我们可以看到第一次分解之后的前者的结果为19+26 后者的结果为15+30(这里只是举个例子)
那么第二次进行分解后,前者为9+10+11+15 后者为7+8+11+19
那么第三次分解后,结果都为7+8+9+10+11,即为所截的木头,不过在第三次分解的时候,
前者花费是15,后者花费是19,也就是说按第一种截法所花费的更少,我们可以发现,第一分解之后
前者结果19+26,两个数之差比后者结果15+30小,此时虽说看两者的花费还是一样的45,不过这为后面
两者的花费不同埋下了伏笔,你可以看到后面的26=11+15,30=11+19,就开始不同了,从15,19可以看出来