P3022 [USACO11OPEN]Odd degrees G

Title Description

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

Input Format

* 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

Output Format

* 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.

Translation of the meaning of problems

The meaning of problems

Cattle were being invaded. There N N points, by a M -free connection to the M side. Undirected edges from A_i A I to B_i B I . Side weight to ensure that no data, but does not guarantee the communication (i.e., not be able to reach from one point to another point).

Cattle know who are planning to invade their inventory of all the edges, so they want to cut off some of the edge of the intruder's plan as much as possible difficulties

Please find a way to leave some edges, so that each point only the odd edges connected to it. And the output side of the program left behind.

Here is a sample

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

Reads the output format

Read format

  • The first line of two integers  N N and  M M
  • The second to M +. 1 M + . 1 lines, each side has a two integers described A_i A I and B_i B I

Output Format

  • The first row of an integer number of edges remaining, the output of -1 if it is impossible please
  • After a number of each line, the number of sides (by order of input).

Thank @ToBiChi translation

Sample input and output

Input # 1
4 4 
1 2 
2 3 
3 1 
3 4 
Output # 1
3 
2 
3 
4 

Description / Tips

Thank @cn: Special Judge Su Qing Nian provided

 

Thinking

  FIG starts updating in the search process by the leaf edges and even, if an odd number of leaves of the upper edge of the current selection does not need to demonstrate added with leaves, can be updated sequence against 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 ;
}

Guess you like

Origin www.cnblogs.com/orangeko/p/12556504.html