coderforces 405E 图论dfs

本文介绍了一种解决特定无向图拆分问题的算法,该算法通过深度优先搜索(DFS)来寻找符合条件的两条相邻边,并以三个点一组的形式输出。文章详细解释了当边的数量为奇数时无解的情况,并提供了完整的C++实现代码。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

点击打开链接

题意:给出一个无向图,将图拆成两条相邻边的形式,输出两条相邻边对应的点,三个一输出

思路:如果m为奇数的话,没有解。用dfs搜索到最底层,如果最底层的边是偶数,则每两个和上一个节点组成一个输出,如果剩下一个的话,则将它存入队列,和其他的边构成后输出。

#include <iostream>
#include <queue>
#include <vector>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <algorithm>
using namespace std;
typedef long long ll;
const int inf=0x3f3f3f3f;
const int maxn=100010;
struct edge{
    int x,pos;
}t;
vector<edge>G[maxn];
bool v[maxn];
int dfs(int now){
    int len=G[now].size();
    edge e;
    queue<int>q;
    for(int i=0;i<len;i++){
        e=G[now][i];
        if(v[e.pos]==0){
            v[e.pos]=1;
            int t=dfs(e.x);
            if(t) printf("%d %d %d\n",now,e.x,t);//now的下一个节点e.x的下面剩下一条边,与now和e.x匹配输出
            else q.push(e.x);
        }
    }
    while(q.size()>=2){
        int t1=q.front();q.pop();
        int t2=q.front();q.pop();
        printf("%d %d %d\n",t1,now,t2);//now节点对应的节点多于两个,则两个和它一匹配输出
    }
    if(!q.empty()) return q.front();
    return 0;
}
int main(){
    int n,m,a,b;
    while(scanf("%d%d",&n,&m)!=-1){
        memset(v,0,sizeof(v));
        for(int i=0;i<m;i++){
            scanf("%d%d",&a,&b);
            t.pos=i;
            t.x=a;
            G[b].push_back(t);
            t.x=b;
            G[a].push_back(t);
        }
        if(m%2) printf("No solution\n");
        else dfs(1);
    }
    return 0;
}

### 关于图论中的深度优先搜索 (DFS) #### 算法原理 在图论中,深度优先搜索是一种用于遍历或搜索树或图的算法。该方法会尽可能深入地探索每一个分支直到无法继续为止,之后再回退并尝试其他未被访问过的节点[^1]。 此过程通过递归调用来完成,在每次进入一个新的顶点时标记其已被访问过以防止形成无限循环;当遇到已访问过的节点或者达到终点条件时即停止当前路径上的前进动作而返回至上一层级重新选择方向进行下一轮探测活动[^2]。 #### 实现方式 ##### 递归实现 以下是基于栈结构模拟函数调用堆栈来执行 DFS 的 Python 版本: ```python def dfs_recursive(graph, start, visited=None): if visited is None: visited = set() visited.add(start) print(start) for neighbor in graph[start]: if neighbor not in visited: dfs_recursive(graph, neighbor, visited) ``` 这段代码定义了一个名为 `dfs_recursive` 的函数,接受三个参数:待搜索图形的数据表示形式(通常是一个字典)、起始位置以及可选的历史记录集合。每当到达新的节点就会将其加入到已经走过的地点列表里,并打印出来作为输出显示;接着依次检查相邻接点是否存在于之前经过的地方之中——如果不存在就再次启动新一轮迭代直至整个网络都被覆盖完毕。 ##### 非递归实现 也可以利用显式的栈数据结构来进行非递归版本的实现: ```python from collections import deque def dfs_iterative(graph, start): stack, path = [start], [] while stack: vertex = stack.pop() if vertex in path: continue path.append(vertex) # Add all unvisited neighbors to the top of the stack. for neighbor in reversed(graph[vertex]): if neighbor not in path: stack.append(neighbor) return path ``` 这里创建了一个空栈并将初始节点压入其中开始处理流程。每一次弹出最上面的一个元素代表正在考察的位置,假如这个位置还没有走过则把它添加至行走轨迹数组之内;随后把所有未曾造访过的邻近区域按照一定顺序推送到队列顶端等待后续检验。最终得到完整的遍历序列。 #### 应用场景 - **图的遍历**:可以有效地找到从源点出发可达的所有其它定点。 - **拓扑排序**:适用于有向无环图(DAG),帮助解决依赖关系管理等问题。 - **连通性分析**:判断两个给定节点之间是否存在一条连接它们的道路。 - **迷宫求解**:可用于自动规划最优路线走出复杂环境。 - **回溯算法**:常应用于组合问题、数独解答等领域。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值