关于拓扑排序的反建图还是一个非常套路的东西

比如说[HNOI2015]菜肴制作

我们希望使得某一个东西在拓扑序中出现的尽可能早,这个时候就可以建出一张反图来,使得这个东西在反图中的拓扑序尽量靠后,从而使得其出现的尽可能地早

这是为什么呢,比如说我们希望\(1\)出现的尽可能早,直接在正图上开一个小根堆来进行拓扑排序显然错的

为什么呢,因为这样只能使字典序尽可能小,而不是使得\(1\)尽可能靠前

但是我们建出反图来呢,显然反图上按照上述方法来跑的话会使得反向字典序最小,而最小的反向字典序一定是\(1\)最靠后的

这道题可以建出一个反图来,从而使得限制条件变成了每一个航班在拓扑序中的位置\(>n-k[i]\),于是我们直接用小根堆来维护\(n-k[i]\)就好了

至于第二问,在每一个点入度为\(0\)可以进堆的时候,我们先不让它进去,而是等某一个元素不满足条件的时候,这个时候就是应该进堆了

代码

#include<iostream>
#include<queue>
#include<cstdio>
#include<cstring>
#define re register
#define mp std::make_pair
#define maxn 2005
struct E
{
int v,nxt;
}e[10005];
int head[maxn],r[maxn],d[maxn];
int c[maxn];
int ans[maxn],tot;
int n,m,num;
typedef std::pair<int,int> pii;
std::priority_queue<pii,std::vector<pii>,std::greater<pii> > q;
inline void add_edge(int x,int y)
{
e[++num].v=y;
e[num].nxt=head[x];
head[x]=num;
}
inline int read()
{
char c=getchar();
int x=0;
while(c<'0'||c>'9') c=getchar();
while(c>='0'&&c<='9')
x=(x<<3)+(x<<1)+c-48,c=getchar();
return x;
}
inline int work(int x)
{
tot=0;
while(!q.empty()) q.pop();
for(re int i=1;i<=n;i++) r[i]=c[i];
for(re int i=1;i<=n;i++)
if(!r[i]) q.push(mp(n-d[i],i));
while(!q.empty())
{
int k=q.top().second;
q.pop();
if(k==x) continue;
if(n-tot>d[k]) return n-tot;
tot++;
for(re int i=head[k];i;i=e[i].nxt)
{
r[e[i].v]--;
if(!r[e[i].v]) q.push(mp(n-d[e[i].v],e[i].v));
}
}
return n-tot;
}
int main()
{
n=read(),m=read();
for(re int i=1;i<=n;i++)
d[i]=read();
int x,y;
for(re int i=1;i<=m;i++)
x=read(),y=read(),add_edge(y,x),r[x]++;
for(re int i=1;i<=n;i++) c[i]=r[i];
for(re int i=1;i<=n;i++)
if(!r[i]) q.push(mp(n-d[i],i));
while(!q.empty())
{
int k=q.top().second;
q.pop();
ans[++tot]=k;
for(re int i=head[k];i;i=e[i].nxt)
{
r[e[i].v]--;
if(!r[e[i].v]) q.push(mp(n-d[e[i].v],e[i].v));
}
}
for(re int i=n;i;i--)
printf("%d ",ans[i]);
puts("");
for(re int i=1;i<=n;i++)
printf("%d ",work(i));
return 0;
}

最新文章

  1. CSS3中的animation动画
  2. On Perseverance
  3. 【python】format函数格式化字符串的用法
  4. JQuery知识快览之二—事件
  5. poj1680 最短路判环
  6. 电脑U盘启动总结
  7. svn 日志 offline 错误
  8. windows下配置wnmp
  9. Lammp安装过程
  10. 网站遭遇DDOS简易处理
  11. 修改MvcPager分页控件以适用Bootstrap 效果(含英文版,可下载)
  12. Toast用法
  13. css 3d 基础知识
  14. js时间比较,获取n天后(前)的日期
  15. VMware下对Ubuntu进行扩充磁盘大小
  16. Oracle SQL*Plus命令
  17. Apache Kafka学习 (二) - 多代理(broker)集群
  18. Magnum Kubernetes源码分析(一)
  19. javascript php 数组 json 对比 总结
  20. 自定义BeanUtils

热门文章

  1. 记DateTime.Now.ToString()遇到的一个坑
  2. 基于Spark GraphX计算二度关系
  3. oracle 多列数据相同,部分列数据不同合并不相同列数据
  4. Hunger Snake
  5. 武汉邀请赛 Key Logger 双向链表
  6. JDBC入门(3)--- PrepareStatement
  7. PoPo数据可视化周刊第5期
  8. springmvc中Controller前端控制器的映射与返回数据,以及异常处理
  9. 利用Java反射实现JavaBean对象相同属性复制并初始化目标对象为空的属性的BeanUtils
  10. TMG 2010 使用脚本来导入URL集和域名集