拓扑排序

做了一些拓扑排序题目来做个总结 怕忘 (老年人记性不好)

1.拓扑排序理论理解

拓扑排序是一种图的运用问题,主要针对的是AOV图,也就是活动步骤这方面的问题解决,特点就是 一步接着一步,做完这一步才能到下一步,不能越界

对应图论来说,重点就是 对于一个结点它的入度是否为0,为0的时候表示这件事情之前的事情已经全部做完,可以开始做这件事了。
当然做完一件事情也要 完全消去这件事 确保其他事能够接着做,(图中只要删除伸出去的边,并减少所连接点的入度即可)

拓扑排序常用解决排名问题,任务安排问题等 一件件事情一个个解决而事于事之间有联系 的问题(还有其他神奇的用途)

2.拓扑排序的板子

拓扑排序哪来的板子

写法方面有一定的规律

建图: (习惯用链式前向星) 我也有博客讲解哦~ 链式前向星图存储优化

struct dd{
	ll e,pr;
}d[N];

ll last[N];
ll cnt=0;
void add(ll f,ll e)  //反向建图
{
    d[++cnt].e=e;
    d[cnt].pr=last[f];
    last[f]=cnt;
}

ll n,m;

int main()
{   
    ios::sync_with_stdio(0);
    cin.tie(0),cout.tie(0);
    
    cin >> n >> m;
    ll f,e;
    vector<ll> in(n+5);  //入度
    while(m--)
    {
    	cin >> f >> e;
    	add(f,e);in[e]++;   //记录入度
    }
	

其他建图也可以,重点在要记录入度值

常用操作:

queue<ll> q;  //常用队列保存入度为0的数并进行下一步操作
for(ri i=1;i<=n;i++)
    if(!in[i]) q.push(i);  
		
ll tp,to;
while(!q.empty())
{
	tp=q.top();q.pop();cout << tp << '\n';
	for(ri i=last[tp];i;i=d[i].pr)
	{
		to=d[i].e;
                // 特殊操作... 
		if(!(--in[to]))  //去边
                  q.push(to);  
	}
}

这些步骤就可以灵活自己变化了,队列可以用优先队列来进行不同要求的改变,特殊操作也可以根据实际情况修改

3.入门题

洛谷拓扑排序题单
洛谷P4017最大食物链
洛谷P2712摄像头
洛谷P1960郁闷的记者

特殊:
HDU1285确定比赛名次
由于排序特殊要求要用到最小堆,也就是优先队列

队列变成:

priority_queue<int,vector<int>,greater<int> >q; //最小堆

保证小的数比大的数先输出(题目要求)

posted @ 2021-07-23 15:27  gonghw403  阅读(45)  评论(0编辑  收藏  举报