您的位置:首页 > 其它

BZOJ 4010 HNOI2015 菜肴制作 拓扑排序+堆

2015-04-22 12:21 253 查看
题目大意:给定一张无向图,求一个拓扑序,使:

1的位置最靠前

在保证上面的条件下使2的位置最靠前

在保证上面的条件下使3的位置最靠前

……

注意不是字典序最小!例如样例3

建立反图,对反图求字典序最大的拓扑序,然后反向输出即可。

我不知道为什么。真的不知道。

求个解答在线等。

#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
#define M 100100
using namespace std;
struct abcd{
int to,next;
}table[M];
int head[M],tot;
int n,m;
int degree[M];
int stack[M],top;
void Add(int x,int y)
{
table[++tot].to=y;
table[tot].next=head[x];
head[x]=tot;
}
void Initialize()
{
memset(head,0,sizeof head);
tot=1;
memset(degree,0,sizeof degree);
}
namespace Priority_Queue{
int heap[M],top;
void Insert(int x)
{
heap[++top]=x;
int t=top;
while(t>1)
{
if(heap[t]>heap[t>>1])
swap(heap[t],heap[t>>1]),t>>=1;
else
break;
}
}
void Pop()
{
heap[1]=heap[top--];
int t=2;
while(t<=top)
{
if( t<top && heap[t+1]>heap[t] )
++t;
if(heap[t]>heap[t>>1])
swap(heap[t],heap[t>>1]),t<<=1;
else
break;
}
}
}
void Topology_Sort()
{
using namespace Priority_Queue;
int i;
for(i=1;i<=n;i++)
if(!degree[i])
Insert(i);
while(Priority_Queue::top)
{
int x=heap[1];Pop();
stack[++::top]=x;
for(i=head[x];i;i=table[i].next)
if(!--degree[table[i].to])
Insert(table[i].to);
}
}
int main()
{
int T,i,x,y;
for(cin>>T;T;T--)
{
Initialize();
scanf("%d%d",&n,&m);
for(i=1;i<=m;i++)
{
scanf("%d%d",&x,&y);
Add(y,x);
degree[x]++;
}
top=0;
Topology_Sort();
if(top!=n)
puts("Impossible!");
else
{
for(i=n;i;i--)
printf("%d ",stack[i],i==1?'\n':' ');
puts("");
}
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息