hdu 4857(拓扑)
来源:互联网 发布:c语言求2的n次平方 编辑:程序博客网 时间:2024/04/29 16:28
这题读完,马上想到是拓扑,但裸拓扑果断wa了。在仔细分析一下,应该加个优先队列,结果又wa了。没办法,参考了下大牛。原来还要拓扑的反向建边。先说拓扑。
拓扑的作用就是排列一组相互有前后关系的数据的算法。最经典的例子就是课程安排。如果让你给一个班级安排课程,有识字,组词,造句,写文章,小学数学。你要如何安排呢?如果是我,果断就是刚才的顺序,先识字,在组词,造句,最后写文章,至于数学,放哪里都行。你在无形中就用到了拓扑排序。拓扑就是本着一些东西必须在另一些东西之前的原则排序的。你不可能还没识字,就让写文章吧。这个算法放到本题,真是太贴切了。下面就介绍一下拓扑的算法思路。介绍之前,必须说一下入度这个名词。所谓入度就是......还是先贴张图再说吧。
画的丑,能说明问题就行。看上图,1的入度0,2的入度2,3的入度0,4的入度1.好了感觉不需要再解释了。
明白入度后就简单了。拓扑的思路就是每次取出入度为0的点,然后把与它相连的点的入度减一,就这样循环,直到所有的点都被取出。像上面的图。第一次取1或3。假设我们取1
则删去1点,1点与2点相连,把2点的入度减一。此时,再取入度为0的点,只能是3了。2与3连,再把2的入度减一,此时2的入度就为0,取出2,4与2相连,4的入度减一,此时4的入度为0,再取出4,结束。保存数据时,可以用个二维数组,第一维代表操作点,第二维代表与操作点相连的点。入度则用一个一维数组保存即可。核心代码
<span style="font-size:18px;">for(int i=1;i<n;i++){cin>>a>>b;if(!arr[a][b])//防重复,比如数据为1,2 1,2 {arr[a][b]=1;rd[b]++;//入度 }}</span>下面介绍一下优先队列,这个不需要过多解释,只给出几种实现形式就够了。
1 c++默认
priority_queue<int> q;默认是按优先级从大到小排列。
2 自定义优先级
struct cmp
{
operator bool ()(int x, int y)
{
return x > y; // x小的优先级高
//也可以写成其他方式,如: return p[x] > p[y];表示p[i]小的优先级高
}
};
priority_queue<int, vector<int>, cmp>q;//定义方法
3 结构体形式
struct node
{
int x, y;
friend bool operator < (node a, node b)
{
return a.x > b.x; //结构体中,x小的优先级高
}
};
priority_queue<node>q;//定义方法
//在该结构中,y为值, x为优先级。
当这些东西懂清楚以后,这题就是1+1了。就是2者结合就行了。上本题代码
<span style="font-size:18px;">#include<iostream>#include<vector>#include<queue>#include<cstring>using namespace std;int rd[30005];int queu[30005];vector<int> a[30005];int n,m;struct cmp{bool operator () (const int &a,const int &b){return a<b;}};priority_queue<int,vector<int>,cmp> q;void topo(){for(int i=1;i<=n;i++){if(rd[i]==0){q.push(i);}}int count=1;while(!q.empty()){int x=q.top();q.pop();for(int i=0;i<a[x].size();i++){rd[a[x][i]]--;if(rd[a[x][i]]==0){q.push(a[x][i]);}}queu[count++]=x;}}int main(){int t;cin>>t;while(t--){cin>>n>>m;for(int i=0;i<=n;i++){rd[i]=0;a[i].clear();}int x,y;while(m--){scanf("%d%d",&x,&y);a[y].push_back(x);rd[x]++;<span style="font-family: 'Microsoft YaHei', lucida, verdana, sans-serif;">//这里就是反向建边,仔细看就so easy。</span>}topo();for(int i=n;i>0;i--){if(i!=1)cout<<queu[i]<<" ";elsecout<<queu[i]<<endl;}}return 0;}</span>
- hdu 4857(拓扑)
- HDU 4857:逃生【拓扑】
- HDU-4857(拓扑排序)
- hdu 4857 拓扑排序
- HDU 4857--逃生【拓扑排序 && 反向拓扑】
- HDU 4857 逃生(拓扑排序)
- hdu-4857-逃生-拓扑排序
- hdu 4857(逆序拓扑排序)
- HDU 4857 逃生(拓扑排序)
- hdu-4857 逃生 拓扑排序
- HDU-4857-逃生【拓扑排序】
- hdu 4857 逃生 (拓扑排序)
- 【HDU】4857--逃生(拓扑)
- 【HDU】4857 逃生 逆拓扑排序
- hdu 4857 逆向拓扑排序+逆向输出
- HDU 4857 逃生 拓扑排序+优先队列
- hdu 4857 逃生(逆向拓扑+优先队列)
- hdu 4857 逆向拓扑排序+反向输出
- 第十二周项目一 阅读程序(一)
- 各种编码UNICODE、UTF-8、ANSI、ASCII、GB2312、GBK详解
- 在线考试系统(一)-----数据库的设计
- Git学习笔记(一)
- 赵常晓:每个人都有自己的特地,我也是这样子
- hdu 4857(拓扑)
- ios 之contentMode 属性
- 微信公众帐号开发教程第14篇-自定义菜单的创建及菜单事件响应
- UTF 8 编码规则
- android AChartEnginee讲解之源码框架解读
- 微信公众帐号开发教程第13篇-图文消息全攻略
- Oracle Connect By的用法
- BASE64 编码原理
- Linux一些常用命令