hdu 6311 欧拉回路

题意:求一个图(不一定联通)最小额外连接几条边,使得可以一笔画出来

大致做法

1.找出联通块

2.统计每一个连通块里面度数为奇数的点的个数,

有一个性质 一个图能够用一笔画出来,奇数点的个数不超过2个

if  奇数点的个数==0  或者 ==1 直接找欧拉回路

else 将除去前面两个奇数点外的奇数点依次相连 然后找欧拉回路

然后记录路径 

 1 #include <cstdio>
 2 #include <cstring>
 3 #include <queue>
 4 #include <cmath>
 5 #include <algorithm>
 6 #include <set>
 7 #include <iostream>
 8 #include <map>
 9 #include <stack>
10 #include <string>
11 #include <vector>
12 #define  pi acos(-1.0)
13 #define  eps 1e-9
14 #define  fi first
15 #define  se second
16 #define  rtl   rt<<1
17 #define  rtr   rt<<1|1
18 #define  bug         printf("******\n")
19 #define  mem(a,b)    memset(a,b,sizeof(a))
20 #define  name2str(x) #x
21 #define  fuck(x)     cout<<#x" = "<<x<<endl
22 #define  f(a)        a*a
23 #define  sf(n)       scanf("%d", &n)
24 #define  sff(a,b)    scanf("%d %d", &a, &b)
25 #define  sfff(a,b,c) scanf("%d %d %d", &a, &b, &c)
26 #define  sffff(a,b,c,d) scanf("%d %d %d %d", &a, &b, &c, &d)
27 #define  pf          printf
28 #define  FRE(i,a,b)  for(i = a; i <= b; i++)
29 #define  FREE(i,a,b) for(i = a; i >= b; i--)
30 #define  FRL(i,a,b)  for(i = a; i < b; i++)+
31 #define  FRLL(i,a,b) for(i = a; i > b; i--)
32 #define  FIN         freopen("data.txt","r",stdin)
33 #define  gcd(a,b)    __gcd(a,b)
34 #define  lowbit(x)   x&-x
35 using namespace std;
36 typedef long long  LL;
37 typedef unsigned long long ULL;
38 const int mod = 1e9 + 7;
39 const int maxn = 2e5 + 10;
40 const int INF = 0x3f3f3f3f;
41 const LL INFLL = 0x3f3f3f3f3f3f3f3fLL;
42 int n, m, ans, du[maxn], vis[maxn], vis1[maxn];
43 struct Edge {
44     int v, id;
45 };
46 vector<Edge>g[maxn];
47 vector<int>cnt, path[maxn];
48 void dfs ( int u ) {
49     vis[u] = 1;
50     if ( du[u] & 1 ) cnt.push_back ( u );
51     for ( int i = 0 ; i < g[u].size() ; i++ ) {
52         if ( vis[g[u][i].v] ) continue;
53         dfs ( g[u][i].v );
54     }
55 }
56 void dfs1 ( int u ) {
57     for ( int i = 0 ; i < g[u].size() ; i++ ) {
58         if ( vis1[abs ( g[u][i].id )] ) continue;
59         vis1[abs ( g[u][i].id )] = 1;
60         dfs1 ( g[u][i].v );
61         if ( abs ( g[u][i].id ) > m ) ans++;
62         else path[ans].push_back ( -g[u][i].id );
63         //欧拉回路的路径是反的  所以要-号
64     }
65 }
66 int main() {
67     while ( ~sff ( n, m ) ) {
68         ans = 0;
69         mem ( vis, 0 ), mem ( vis1, 0 );
70         for ( int i = 1 ; i <= n ; i++ ) path[i].clear(), g[i].clear(), du[i] = 0;
71         for ( int i = 1, u, v ; i <= m ; i++ ) {
72             sff ( u, v );
73             g[u].push_back ( {v, i} );
74             g[v].push_back ( {u, -i} );
75             du[u]++, du[v]++ ;
76         }
77         int num = m;
78         for ( int i = 1 ; i <= n ; i++ ) {
79             if ( !vis[i] && du[i] ) {
80                 cnt.clear();
81                 dfs ( i );
82                 ans++;
83                 if ( cnt.size() == 0 ) cnt.push_back ( i );
84                 for ( int j = 2 ; j < cnt.size() ; j += 2 ) {
85                     g[cnt[j]].push_back ( {cnt[j + 1], ++num} );
86                     g[cnt[j + 1]].push_back ( {cnt[j], -num} );
87                 }
88                 dfs1 ( cnt[0] );
89             }
90         }
91         printf ( "%d\n", ans );
92         for ( int i = 1 ; i <= ans; i++ ) {
93             printf ( "%d", path[i].size() );
94             for ( int j = 0 ; j < path[i].size() ; j++ ) printf ( " %d", path[i][j] );
95             printf ( "\n" );
96         }
97     }
98     return 0 ;
99 }

猜你喜欢

转载自www.cnblogs.com/qldabiaoge/p/10461649.html