Fleury(弗洛莱)算法实现

来源:互联网 发布:新部落冲突4级地震数据 编辑:程序博客网 时间:2024/06/08 09:05

图论~~·模板

无向图:书上的代码看不懂啊,,邻接表,栈之类的。自学之路。。。。。

#include<iostream>#include<cstdio>#include<cstring>#include<string.h>#include<algorithm>#include<vector>using namespace std;const int N = 1005;int n, m, flag, top, sum, du, ans[5005], map[N][N];void dfs(int x){    top++;    ans[top] = x;    for(int i = 1; i <= n; i++)    {        if(map[x][i] >0)        {            map[x][i]=0;            map[i][x]=0;            dfs(i);            break;        }    }}void fleury(int x){    top = 1;    ans[top] = x;    while(top > 0)    {        int k = 0;        for(int i = 1; i <= n; i++)//判断是否可扩展        {            if(map[ans[top]][i] >0)//若存在一条从ans[top]出发的边  那么就是可扩展            {                k = 1;                break;            }        }        if(k == 0)//该点x没有其他的边可以先走了(即不可扩展), 那么就输出它        {            printf("%d ", ans[top]);            top--;        }        else if(k == 1)//如可扩展, 则dfs可扩展的哪条路线        {            top--;//这需要注意,为了回溯            dfs(ans[top+1]);        }    }}int main(){    while(scanf("%d%d", &n, &m) != EOF)    {        // memset(du, 0, sizeof(du));        memset(map, 0, sizeof(map));        for(int i = 1; i <= m; i++)        {            int x, y;            scanf("%d%d", &x, &y);            map[x][y]=1; //记录边, 因为是无向图所以加两条边, 两个点之间可能有多条边            map[y][x]=1;        }        flag = 1; // flag标记开始点。 如果所有点度数全为偶数那就从1开始搜        sum = 0;        for(int i = 1; i <= n; i++)        {            du=0;            for(int j=1; j<=n; j++)                du+=map[i][j];            if(du % 2 == 1)            {                sum++;                flag = i;// 若有奇数边, 从奇数边开始搜            }        }        if(sum == 0 || sum == 2)            fleury(flag);    }    return 0;}/*9 141 2 1 8 2 3 2 8 2 9 3 4 4 5 4 6 4 9 5 6 6 7 6 9 7 8 8 9*/
题目链接:快速查找243页例5.8
#include<iostream>#include<cstdio>#include<cstring>#include<string.h>#include<algorithm>#include<vector>using namespace std;const int N = 1005;int n, m, flag, top, sum, du[N], ans[5005], map[N][N];void dfs(int x){    ans[++top] = x;    for(int i = 1; i <= n; i++)    {        if(map[x][i] >= 1)        {            map[x][i]--;            map[i][x]--;            dfs(i);            break;        }    }}void fleury(int x){    top = 1;    ans[top] = x;    while(top > 0)    {        int k = 0;        for(int i = 1; i <= n; i++)//判断是否可扩展        {            if(map[ans[top]][i] >= 1)//若存在一条从ans[top]出发的边  那么就是可扩展            {k = 1; break;}        }        if(k == 0)//该点x没有其他的边可以先走了(即不可扩展), 那么就输出它        {            printf("%d ", ans[top]);            top--;        }        else if(k == 1)//如可扩展, 则dfs可扩展的哪条路线        {            top--;//这需要注意            dfs(ans[top+1]);        }    }}int main(){    while(scanf("%d%d", &n, &m) != EOF)    {        memset(du, 0, sizeof(du));        memset(map, 0, sizeof(map));        for(int i = 1; i <= m; i++)        {            int x, y;            scanf("%d%d", &x, &y);            map[x][y]++; //记录边, 因为是无向图所以加两条边, 两个点之间可能有多条边            map[y][x]++;            du[x]++;            du[y]++;        }        flag = 1; // flag标记开始点。 如果所有点度数全为偶数那就从1开始搜        sum = 0;        for(int i = 1; i <= n; i++)        {            if(du[i] % 2 == 1)            {                sum++;                flag = i;// 若有奇数边, 从奇数边开始搜            }        }        if(sum == 0 || sum == 2)            fleury(flag);    }    return 0;}


原创粉丝点击