Advertisement
oToToT

Untitled

Jun 18th, 2019
119
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 2.76 KB | None | 0 0
  1. #include <bits/stdc++.h>
  2. using namespace std;
  3. const int N = 10000000 + 5;
  4.  
  5. set< pair< int, int > > st;
  6.  
  7. int to[ N << 1 ], nxt[ N << 1 ], hd[ N ];
  8. bool vis[ N ];
  9. int from[ N ], qu[ N ], deg[ N ], sd[ N ];
  10.  
  11. int main() {
  12.     ios_base::sync_with_stdio( false );
  13.     cin.tie( nullptr );
  14.  
  15.     memset( hd, -1, sizeof( hd ) );
  16.     int n, m; cin >> n >> m;
  17.  
  18.     // 特判無解
  19.     if ( m == 0 ) {
  20.         cout << -1 << '\n';
  21.         return 0;
  22.     }
  23.  
  24.     // 讀入所有的邊
  25.     for ( int i = 0 ; i < m ; ++ i ) {
  26.         int u, v; cin >> u >> v;
  27.         nxt[ i * 2 ] = hd[ u ];
  28.         to[ i * 2 ] = v;
  29.         hd[ u ] = i * 2;
  30.  
  31.         nxt[ i * 2 + 1 ] = hd[ v ];
  32.         to[ i * 2 + 1 ] = u;
  33.         hd[ v ] = i * 2 + 1;
  34.  
  35.         deg[ u ] ++, deg[ v ] ++;
  36.         st.insert( minmax( u, v ) );
  37.     }
  38.  
  39.     // 考慮每個連通塊
  40.     for ( int i = 1 ; i <= n ; ++ i ) {
  41.         // 有解就會結束,所以應該不能被遍歷過
  42.         assert( not vis[ i ] );
  43.  
  44.         // 如果他沒有連其他人,那就可以考慮其他人
  45.         if ( hd[ i ] == -1 ) {
  46.             assert( deg[ i ] == 0 );
  47.             continue;
  48.         }
  49.  
  50.         // bfs整個連通塊,找到degree一樣的兩個點,放在r1跟r2裡
  51.         int qs = 0, qe = 0;
  52.         int r1 = -1, r2 = -1;
  53.         qu[ qe ++ ] = i;
  54.         vis[ i ] = true;
  55.         while ( qs < qe ) {
  56.             int u = qu[ qs ++ ];
  57.             if ( sd[ deg[ u ] ] )
  58.                 r1 = u, r2 = sd[ deg[ u ] ];
  59.             sd[ deg[ u ] ] = u;
  60.             for ( int _ = hd[ u ] ; _ != -1 ; _ = nxt[ _ ] ) {
  61.                 if ( vis[ to[ _ ] ] ) continue;
  62.                 vis[ to[ _ ] ] = true;
  63.                 qu[ qe ++ ] = to[ _ ];
  64.             }
  65.         }
  66.         // 理論上一定會找到解
  67.         assert( r1 != -1 );
  68.         // 重新以r1 bfs一次,找出r1->r2的一條路徑
  69.         for ( int _ = 0 ; _ < qe ; ++ _ )
  70.             vis[ qu[ _ ] ] = false;
  71.         qs = 0, qe = 0;
  72.         qu[ qe ++ ] = r1;
  73.         vis[ r1 ] = true;
  74.         while ( qs < qe ) {
  75.             int u = qu[ qs ++ ];
  76.             for ( int _ = hd[ u ] ; _ != -1 ; _ = nxt[ _ ] ) {
  77.                 if ( vis[ to[ _ ] ] ) continue;
  78.                 vis[ to[ _ ] ] = true;
  79.                 qu[ qe ++ ] = to[ _ ];
  80.                 from[ to[ _ ] ] = u;
  81.             }
  82.         }
  83.         // 確實找出那條路徑
  84.         vector< int > path;
  85.         while( r2 != r1 ) {
  86.             path.push_back( r2 );
  87.             r2 = from[ r2 ];
  88.         }
  89.         path.push_back( r1 );
  90.  
  91.         // 確定自己走的路徑是合法的
  92.         int xr = 0, la = -1;
  93.         for ( size_t _ = 1 ; _ + 1 < path.size() ; ++ _ ) {
  94.             cout << path[ _ ] << ' ';
  95.             xr ^= deg[ path[ _ ] ];
  96.             if ( la != -1 )
  97.                 assert( st.find( minmax( la, path[ _ ] ) ) != st.end() );
  98.             la = path[ _ ];
  99.         }
  100.         for ( size_t _ = 1 ; _ <= path.size() ; ++ _ ) {
  101.             cout << path[ path.size() - _ ] << " \n"[ _ == path.size() ];
  102.             xr ^= deg[ path[ path.size() - _ ] ];
  103.             if ( la != -1 )
  104.                 assert( st.find( minmax( la, path[ path.size() - _ ] ) ) != st.end() );
  105.             la = path[ path.size() - _ ];
  106.         }
  107.         assert( xr == 0 );
  108.         return 0;
  109.     }
  110.     // 無解應該要只有m==0的時候才會發生
  111.     assert( false );
  112.     return 0;
  113. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement