拓扑排序 和 欧拉道路

拓扑排序

<style type="text/css"> <!-- @page {margin:2cm} p {margin-bottom:0.21cm; direction:ltr; color:#000000; text-align:justify; widows:0; orphans:0} p.western {font-family:"Times New Roman",serif; font-size:10pt} p.cjk {font-family:"宋体","SimSun"; font-size:10pt} p.ctl {font-family:"Times New Roman",serif; font-size:12pt} --> </style>

对于一个有向无环图来说,存在一个先后的顺序来执行动作,然后我们可以找到其中的一种方法就是拓扑排序的,注意拓扑排序是有向的

模板:

vis[]数组标记是否走过该节点num[][]存储这个无环图的数值ans[]存储一种顺序n是最大编号

//深搜(从后向前然后倒着存储ans

booldfs(int i){

vis[i]= -1;

for(intj = 1 ; j <= n; j++){枚举每一行

if(num[i][j]== 1){该点有数值才满足

if(!vis[j])如果该点没标记过就继续递归下去

dfs(j)递归调用

}

}

vis[i]= 1;从新赋值为1

ans[t--]= I;倒着存储

return true;

}

//拓扑排序

booltoposort(){

t= n;初始化为n

memset(vis, 0 , sizeof(vis));初始化为0

for(inti = 1 ; i <= n; i++){枚举n个编号

if(vis[i]== 0){没被走过的才满足

dfs(i);递归调用

}

}

return true;

}

<style type="text/css"> <!-- @page {margin:2cm} p {margin-bottom:0.21cm; direction:ltr; color:#000000; text-align:justify; widows:0; orphans:0} p.western {font-family:"Times New Roman",serif; font-size:10pt} p.cjk {font-family:"宋体","SimSun"; font-size:10pt} p.ctl {font-family:"Times New Roman",serif; font-size:12pt} --> </style>

2欧拉道路:在欧拉道路中,对于起点而言它的入度=出度–1,对于终点而言出度=入度-1,其它的点的的入度和出度是相等的并且是偶数。

1(特殊的欧拉道路:欧拉回路----起点的终点重回,所有点的度数为偶数)

2有向图的结论:最多只能有两个点的入度不等于出度,而且其中一个点的出度恰好比入度大1(起点),另一个点的入度比出度的1(终点)

3无向图:如果默认是无向的话,图必须为连通的



欧拉道路的路径输出

1无向图的邻阶矩阵 map[MAXN][MAXN]

2存储节点的坐标的结构体

struct node{

intx;

inty;

};

<style type="text/css"> <!-- @page {margin:2cm} p {margin-bottom:0.21cm; direction:ltr; color:#000000; text-align:justify; widows:0; orphans:0} p.western {font-family:"Times New Roman",serif; font-size:10pt} p.cjk {font-family:"宋体","SimSun"; font-size:10pt} p.ctl {font-family:"Times New Roman",serif; font-size:12pt} --> </style>

3代码:

void euler(int u){

<style type="text/css"> <!-- @page {margin:2cm} p {margin-bottom:0.21cm; direction:ltr; color:#000000; text-align:justify; widows:0; orphans:0} p.western {font-family:"Times New Roman",serif; font-size:10pt} p.cjk {font-family:"宋体","SimSun"; font-size:10pt} p.ctl {font-family:"Times New Roman",serif; font-size:12pt} --> </style>

for(inti = 0 ; i <= 50 ; i++){

if(map[u][i]){

<style type="text/css"> <!-- @page {margin:2cm} p {margin-bottom:0.21cm; direction:ltr; color:#000000; text-align:justify; widows:0; orphans:0} p.western {font-family:"Times New Roman",serif; font-size:10pt} p.cjk {font-family:"宋体","SimSun"; font-size:10pt} p.ctl {font-family:"Times New Roman",serif; font-size:12pt} --> </style>

--map[i][u];

euler(i);//继续向下搜索

node temp;

temp.x= u ; temp.y = i;

s.push(temp);//把点压入栈中(逆序输出)

}

}

}

<style type="text/css"> <!-- @page {margin:2cm} p {margin-bottom:0.21cm; direction:ltr; color:#000000; text-align:justify; widows:0; orphans:0} p.western {font-family:"Times New Roman",serif; font-size:10pt} p.cjk {font-family:"宋体","SimSun"; font-size:10pt} p.ctl {font-family:"Times New Roman",serif; font-size:12pt} --> </style>

4输出(逆序输出)

while!s.empty(){

node temp;

temp = s.top();

printf(“%d%d\n” , temp.x , temp.y);

s.pop();

}











<style type="text/css"> <!-- --> </style>

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值