zoukankan      html  css  js  c++  java
  • 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


  • 相关阅读:
    python:linux中升级python版本
    robot:当用例失败时执行关键字(发送短信)
    robot:根据条件主动判定用例失败或者通过
    robot:List变量的使用注意点
    python:动态参数*args
    robot:linux下安装robot环境
    robot:循环遍历数据库查询结果是否满足要求
    爬虫结果数据完整性校验
    ChromeDriver与chrome对应关系
    Spring系列之AOP
  • 原文地址:https://www.cnblogs.com/lysr--tlp/p/adfs.html
Copyright © 2011-2022 走看看