Codeforces 405 E. Graph Cutting ( DFS )

题意:

给n个点,m条边,将这个图拆成多个子图,每个子图里面有两条相邻的边(也就是每个子图 3个点2条边),当然每条边只能属于一个子图,如果不能拆分成功,则No solution, 否则,将每个子图的3个顶点(x,y,z)输出 (这个子图包含 x到y 的边 , y到z的边 )

思路
m是奇数,则不能拆分。
m是偶数,可以拆分。

1、将图形看成以1为树根的一棵“树”,这棵树会有环,把它当成一颗简单树来分析思路,如下图的一棵树。
  题目中的是无向图,画图的时候不小心画成了有向的了,,,,,(只要把它当成无向就好了,忽视箭头就好了)



2、从树根 1 开始遍历,一直到叶子节点(或者遇到已经被访问过的点),然后进行一些操作,然后回溯。
操作为:
给每个点一个队列来存放它的可用的子节点(存进去的可用的子节点,指的是这个点到子节点的边还未用过)。
然后让这些可用的子节点两两一对,(即child1,root,child2 为一个子图 )。
  如果可用的子节点为奇数,则说明有一条到子节点的边没有被用过,则另外需要当前这个点到它父亲节点的一条边,使之构成一个子图。
例如 图中的 节点3 : 它有3个子节点,(6—3—8)一个子图,3—9这条边则需要和3—1这条边组成一个子图(1—3—9),所以节点3这个点不再是节点1的可用的子节点了,因为1—3 这条边已经被用过了。
  如果可用的子节点是偶数,则不需要直接构成子图就好了。当然这个节点仍然是它父亲节点的可用子节点。如节点2仍然是节点1的子节点。

 1 #include<stdio.h>
 2 #include<string.h>
 3 #include<iostream>
 4 #include<algorithm>
 5 #include<vector>
 6 #include<queue>
 7 
 8 using namespace std;
 9 
10 const int T=1e5+5;
11 
12 struct node
13 {
14     int x,num;
15 }t;
16 
17 vector < node > Q[T];
18 bool flag[T];
19 
20 int dfs( int now )
21 {
22     int l=(int)Q[now].size(),r,v1,v2;
23     node k;
24     queue < int > q;   // 注意==>是每个节点都有一个队列
25     for(int i=0;i<l;i++)
26     {
27         k=Q[now][i];
28         if( flag[k.num] ) continue;
29         flag[k.num]=1;
30         r = dfs( k.x );
31         if( r ) printf("%d %d %d
",now,k.x,r); // 说明 now 节点的子节点有一条未用的边
32         else q.push( k.x );  //否则将这个节点存入到队列里
33     }
34     while( q.size() >= 2 )
35     {
36         v1=q.front();
37         q.pop();
38         v2=q.front();
39         q.pop();
40         printf("%d %d %d
",v1,now,v2);
41     }
42     if( !q.empty() )
43     {
44         v1=q.front();
45         return v1;  // 如果队列里面有剩余,则将此队列里的点返回回去和其父节点,父节点的父节点构成一个子图
46     }
47     return 0;
48 }
49 
50 int main( )
51 {
52     int n,m,a,b;
53     while(~scanf("%d%d",&n,&m))
54     {
55         for(int i=0;i<=n;i++)
56             Q[i].clear();
57         for(int i=1;i<=m;i++)
58         {
59             scanf("%d%d",&a,&b);
60             t.num=i;
61             t.x=b;
62             Q[a].push_back( t );
63             t.x=a;
64             Q[b].push_back( t );
65         }
66         if( m%2 ) printf("No solution
");
67         else{
68 
69             memset(flag,0,sizeof(flag));
70             dfs( 1);
71         }
72     }
73     return 0;
74 }
View Code


原文地址:https://www.cnblogs.com/lysr--tlp/p/adfs.html