题意:如上图所示,给定一个连通的无向图,每条边长度为1,把他的边划分成若干个长度为2的路径。
思路:若边的条数为奇数则不能划分。偶数则一定存在解。
1.对于一个点v,首先将与他相邻且还未被标记的边找出{u|(u,v)未被标记}。并将这些边标记。
2.对这些点递归进行找扩展的点,若能找到拓展的点w 则 输出 v u w,若不能找到,则将这些点存下来。
3.对于为找到 匹配的点 2个未找到匹配的点 与v 可以构成 一条长度为2 的路径。
4.若为匹配点最后有剩余,则这个点为 v 点 的拓展点。
#include<iostream>
#include<cstring>
#include<cstdio>
#include<algorithm>
#include<cmath>
#include<vector>
#include<map>
#include<queue>
#define MOD 1000000007
#define eps 1e-12
#define N 200050
#define M 1000050
using namespace std;
struct edge
{
int to,nx;
}e[N];
int head[N];
int num=0;
bool bo[N];
void addedge(int x,int y)
{
e[num].to=y;
e[num].nx=head[x];
head[x]=num++;
}
bool ok[N];
int gao(int now)
{
ok[now]=true;
queue<int>q;
for(int p=head[now];p!=-1;p=e[p].nx)
{
if(!bo[p])
{
q.push(e[p].to);
bo[p]=bo[p^1]=true;
}
}
queue<int>p;
while(!q.empty())
{
int u=q.front();
q.pop();
int w=gao(u);
if(w!=0)
printf("%d %d %d\n",w,u,now);
else
p.push(u);
}
while(p.size()>=2)
{
int u,v;
u=p.front();
p.pop();
v=p.front();
p.pop();
printf("%d %d %d\n",u,now,v);
}
if(!p.empty())return p.front();
else return 0;
}
int main() {
int i,j,k,n,m;
num=0;
memset(head,-1,sizeof(head));
memset(ok,0,sizeof(ok));
memset(bo,0,sizeof(bo));
scanf("%d%d",&n,&m);
for(i=0;i<m;i++)
{
int x,y;
scanf("%d%d",&x,&y);
addedge(x,y);
addedge(y,x);
}
if(m%2)printf("No solution\n");
else
{
gao(1);
}
}
本文介绍了一种解决特定无向图问题的算法——如何将图的所有边划分成长度为2的路径。针对连通无向图,文章详细阐述了算法的实现思路,包括检查解的存在性条件以及具体步骤,并提供了完整的C++代码实现。

612

被折叠的 条评论
为什么被折叠?



