题目描述

The cows are being invaded! Their republic comprises N (1 <= N <= 50,000) towns that are connected by M (1 <= M <= 100,000) undirected paths between two towns A_i and B_i (1 <= A_i <= N; 1 <= B_i <= N; A_i != B_i; no duplicate paths will occur). However the republic is not necessarily connected--there may be pairs of towns that are unable to reach each other through the paths.

The cows know their invaders plan to conduct an inventory of every path within their republic, so they are willing to shut down various paths to make it as difficult as possible for their invaders to do so.

Please help the cows find a way to shut down a subset of the paths such that each town has an odd number of remaining paths connected to it, or determine if no such subset exists.

For example, consider the following cow republic:

1---2 \ / 3---4 If we keep the paths 1-3, 2-3, and 3-4, and remove the path 1-2, then towns 1, 2, and 4 will be an endpoint of exactly one path, whereas town 3 will be an endpoint of three paths:

1 2 \ / 3---4

输入格式

* Line 1: Two space-separated integers: N and M

* Lines 2..M+1: Line i+1 contains two space-separated integers: A_i and B_i

输出格式

* Line 1: A single integer that is the number of paths to keep. If no subset exists output only a single line with the integer -1.

* Lines 2..K+1: Each line contains an index of an path to keep, in the range 1..M. These indices must be pairwise distinct.

题意翻译

题意

牛们正在被入侵。 有NN个点,由MM条无向边连接。 无向边从A_iAiB_iBi。数据保证无重边,但不保证连通(即从一个点不一定能到达另一点)。

牛知道入侵他们的人正计划清点所有的边,所以他们想切掉一些边使入侵者的计划尽可能的困难

请找出一个方法,留下一些边,使每个点都只有奇数条边与之连接。并输出留下的边的方案。

下面是一个样例

1---2
 \ /
  3---4
我们把1——2那条边拆掉, 就会变成下图
1   2
 \ /
  3---4
对于每个点都只有奇数条边连接,符合题意

读入输出格式

读入格式

  • 第一行两个整数 NN 和 MM
  • 第二到M+1M+1行,每行描述一条边 有两个整数A_iAiB_iBi

输出格式

  • 第一行一个整数 剩下边的数量,如果不可能请输出-1
  • 之后每一行一个数,边的编号(按输入顺序来)。

感谢@ToBiChi 提供翻译

输入输出样例

输入 #1<button class="copy&#45;btn lfe&#45;form&#45;sz&#45;middle" data&#45;v&#45;370e72e2="" data&#45;v&#45;52f2d52f="" type="button">复制</button>
4 4 
1 2 
2 3 
3 1 
3 4 
输出 #1<button class="copy&#45;btn lfe&#45;form&#45;sz&#45;middle" data&#45;v&#45;370e72e2="" data&#45;v&#45;52f2d52f="" type="button">复制</button>
3 
2 
3 
4 

说明/提示

感谢@cn:苏卿念 提供的Special Judge

 

思路

  在图上搜索的过程中由叶子的连边情况开始更新,如果叶子上边数为奇数则证明当前选择的边不需要加入叶子的边,逆着dfs序来更新即可

 

CODE

 

#include  < bits/stdc++.h >
#define  dbg( x ) cout  <<  #x  <<  " = "  << x  << endl
#define  eps  1 e - 8
#define  pi  acos( - 1.0 )

using  namespace std ;
typedef  long  long LL ;

const  int inf  =  0x 3f3f3f3f ;

template < class T > inline  void  read(& res )
{
     char c ;T flag = 1 ;
     while((c = getchar()) < ' 0 ' ||c > ' 9 ' )if(c == ' - ' )flag =- 1 ;res =c - ' 0 ' ;
     while((c = getchar()) >= ' 0 ' &&c <= ' 9 ' )res =res * 10 +c - ' 0 ' ;res *=flag ;
}

namespace _buff  {
     const  size_t BUFF  =  1  <<  19 ;
     char  ibuf [BUFF ],  *ib  = ibuf ,  *ie  = ibuf ;
     char  getc()  {
         if  (ib  == ie )  {
            ib  = ibuf ;
            ie  = ibuf  +  fread(ibuf ,  1 , BUFF , stdin );
         }
         return ib  == ie  ?  - 1  :  *ib ++ ;
     }
}

int  qread()  {
     using  namespace _buff ;
     int ret  =  0 ;
     bool pos  =  true ;
     char c  =  getc();
     for  (;  (<  ' 0 '  || c  >  ' 9 ' )  && c  !=  ' - ' ; c  =  getc())  {
         assert( ~c );
     }
     if  (==  ' - ' )  {
        pos  =  false ;
        c  =  getc();
     }
     for  (; c  >=  ' 0 '  && c  <=  ' 9 ' ; c  =  getc())  {
        ret  =  (ret  <<  3 )  +  (ret  <<  1 )  +  (^  48 );
     }
     return pos  ? ret  :  -ret ;
}

const  int maxn  =  1 e 5  +  7 ;

int n , m , cnt ;

int  edge [maxn  <<  1 ],  head [maxn  <<  1 ],  nxt [maxn  <<  1 ];
int  id [maxn  <<  1 ];

void  BuildGraph( int  u ,  int  v ,  int  idx )  {
     ++cnt ;
     edge [cnt ]  = v ;
     nxt [cnt ]  =  head [u ];
     head [u ]  = cnt ;
     id [cnt ]  = idx ;
}

vector <int> ans ;
bool  vis [maxn ];

bool  dfs( int  u ,  int  fa ,  int  idx )  {
     int du  =  0 ;
     vis [u ]  =  1 ;
     for  (  int i  =  head [u ]; i ; i  =  nxt [i ]  )  {
         int v  =  edge [i ];
         if( vis [v ]  || v  == fa )
             continue;
         if(dfs(v , u ,  id [i ]))
             ++du ;
     }
     if(du  &  1 )  {
         return  false ;
     }
     ans .push_back(idx );
     return  true ;
}

int  main()
{
     read(n );read(m );
     for  (  int i  =  1 ; i  <= m ;  ++)  {
         int u , v ;
         read(u );read(v );
         BuildGraph(u , v , i );
         BuildGraph(v , u , i );
     }
     for  (  int i  =  1 ; i  <= n ;  ++)  {
         if( vis [i ])
             continue;
         if(dfs(i ,  0 ,  0 ))  {
             puts( " -1 " );
             return  0 ;
         }
     }
     int d  =  ans .size();
    cout  << d  << endl ;
     for  (  int i  =  0 ; i  < d ;  ++)  {
        cout  <<  ans [i ]  << endl ;
     }
     return  0 ;
}