Description
champ最近在修改一个游戏,他希望通过修改得到一个拥有全属性、全装备、全物品……的存档。
经过champ初步统计,它需要修改N个数据才能达到目的。(数据编号从1到N)
由于游戏本身采取了一些反作弊措施,有时会将用Ai数据去恢复Bi数据。所以champ修改数据时必须先修改Ai然后再修改Bi,以防止程序出错或崩溃。
现在,champ采集了充足的数据,希望你给他一个修改数据的顺序,正确安全的修改数据。注意,champ的n个数据都要修改。
Input
多组数据测试
每组数据第一行两个数N K(N<100000,K<1000000)
之后K行每行两个数Ai Bi(0<Ai,Bi<=N Ai!=Bi) (i=1,2,...,K)
同一组限制不会出现两次
数据以两个0结束
Output
每组数据一行,输出可行顺序的最小字典序。可行顺序一定存在。
Sample Input
5 6
1 4
4 3
1 5
5 3
1 3
2 4
0 0
Sample Output
ORDER: 1 2 4 5 3
Hint
我们可以把n个数据和它们之间的关系抽象成一个图,每个顶点代表一个数据,如果在修改a之前必须修改b,那么a到b之间有一条边a->b。这样,可以抽象成一个有向无环图。
对应于sample的图
输入输出巨大,请使用scanf,同时输出使用printf。
Source
champ最近在修改一个游戏,他希望通过修改得到一个拥有全属性、全装备、全物品……的存档。
经过champ初步统计,它需要修改N个数据才能达到目的。(数据编号从1到N)
由于游戏本身采取了一些反作弊措施,有时会将用Ai数据去恢复Bi数据。所以champ修改数据时必须先修改Ai然后再修改Bi,以防止程序出错或崩溃。
现在,champ采集了充足的数据,希望你给他一个修改数据的顺序,正确安全的修改数据。注意,champ的n个数据都要修改。
Input
多组数据测试
每组数据第一行两个数N K(N<100000,K<1000000)
之后K行每行两个数Ai Bi(0<Ai,Bi<=N Ai!=Bi) (i=1,2,...,K)
同一组限制不会出现两次
数据以两个0结束
Output
每组数据一行,输出可行顺序的最小字典序。可行顺序一定存在。
Sample Input
5 6
1 4
4 3
1 5
5 3
1 3
2 4
0 0
Sample Output
ORDER: 1 2 4 5 3
Hint
我们可以把n个数据和它们之间的关系抽象成一个图,每个顶点代表一个数据,如果在修改a之前必须修改b,那么a到b之间有一条边a->b。这样,可以抽象成一个有向无环图。
对应于sample的图
输入输出巨大,请使用scanf,同时输出使用printf。
Source
champ
很显然的拓扑排序,用优先队列处理一下,否则超时。
#include<iostream>
#include<queue>
using namespace std;
const int M=1000005,N=100005;
struct Edge
{
int v,next;
}edge[M];
int edgehead[N];
int k;
int n,m;
int indgr[N];
void addedge(int u,int v)
{
edge[k].v=v;
indgr[v]++;
edge[k].next=edgehead[u];
edgehead[u]=k++;
}
void topo()
{
priority_queue< int,vector<int>,greater<int> > que;
for(int i=1;i<=n;i++)
{
if(!indgr[i])
que.push(i);
}
while(!que.empty())
{
int now=que.top();
que.pop();
for(int j=edgehead[now];j;j=edge[j].next)
{
int v=edge[j].v;
indgr[v]--;
if(indgr[v]==0)
que.push(v);
}
printf(" %d",now);
indgr[now]=-1;
}
}
int main()
{
while(scanf("%d%d",&n,&m),n!=0||m!=0)
{
k=1;
memset(indgr,0,sizeof(indgr));
memset(edge,0,sizeof(edge));
memset(edgehead,0,sizeof(edgehead));
int u,v;
for(int i=1;i<=m;i++)
{
scanf("%d%d",&u,&v);
addedge(u,v);
}
printf("ORDER:");
topo();
printf("\n");
}
return 0;
}