欧拉回路 + 数据结构 + dfs

poj 2230

这个题确实很经典。刚开始的时候想了好久,一直没想明白怎么去遍历所有的点两遍。搜了,别人的解题报告。顿悟,标记边啊。太弱了。。然后保存成动态邻接表的形式。深搜一遍就过了。。后来看到一大牛博客上的解法,瞬间,觉得,那种相对邻接表保存的数据结构,简直碉堡了,神牛果然是用来学习的。。

邻接表:

#include <iostream>
#include <vector>
#include <cstdio>
#define N 100005
using namespace std;
int n,m;
struct node
{
    int v,f;
};
vector<node> g[N];
void dfs(int k)
{
    for(int i=0 ;i<g[k].size() ; i++)
    {
        if(g[k][i].f)
        {
            g[k][i].f=0;
            dfs(g[k][i].v);
        }
    }
    printf("%d\n",k);
}
int main ()
{
    int i;
    //freopen("1.txt","r",stdin);
    while(scanf("%d%d",&n,&m)!=EOF)
    {
        int x,y;
        for(i=0 ; i<m ; i++)
        {
            node t;
            scanf("%d%d",&x,&y);
            //x->y
            t.v=y,t.f=1;
            g[x].push_back(t);
            //y->x
            t.v=x,t.f=1;
            g[y].push_back(t);
        }
        dfs(1);
    }
    return 0;
}


大牛的强势保存形式:

#include <iostream>
#include <cstdio>
#include <cstring>
#include <string>
#define N 100005
using namespace std;
bool f[N];
struct node
{
    int t,nx;
}e[N];
int n,m,a[N],nt;
void dfs(int k)
{
    int v;
    for(v=a[k] ; v!=-1 ; v=e[v].nx)
    {
        if(!f[v])
        {
            f[v]=1,dfs(e[v].t);
        }
    }
    printf("%d\n",k);
}
int main ()
{
    //freopen("1.txt","r",stdin);
    while(scanf("%d%d",&n,&m)!=EOF)
    {
        int i,x,y;
        memset(f,0,sizeof(f));
        memset(a,-1,sizeof(a));
        for(nt=i=0 ; i<m ; i++)
        {
            scanf("%d%d",&x,&y);
            //x->y
            e[nt].t=y,e[nt].nx=a[x],a[x]=nt++;
            //y->x
            e[nt].t=x,e[nt].nx=a[y],a[y]=nt++;
        }
        dfs(1);
    }
    return 0;
}
btw:要理解 后面那段代码的保存结构,建议自己画图。 (个人以最近孩子的概念,每个节点保存了 ta上一个兄弟节点的信息。。)


  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值