题意:求一个图(不一定联通)最小额外连接几条边,使得可以一笔画出来
大致做法
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("****** ") 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 ", 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 ( " " ); 96 } 97 } 98 return 0 ; 99 }