답안 #859549

# 제출 시각 아이디 문제 언어 결과 실행 시간 메모리
859549 2023-10-10T10:02:12 Z KaleemRazaSyed Pipes (CEOI15_pipes) C++17
100 / 100
2166 ms 14596 KB
#include<cstdio>
#include<vector>

using namespace std;

const int N = 100001, K = 18;
int par[N][K]; // par[v][k] = parent at level 2^k above v
int cycle[N]; // cycle[i] = count of the #cycle in which edge i ---> par[i][0] is used
int sz[N]; // sz[i] = size of the component whose root is i
int dsuPar[N]; // dsuPar[i] = parent in dsu 
int h[N]; // h[i] = dis(i, root) where {i, root} are in same component 
vector<int> G[N];

void dfs_cycle(int &v, int &p)
{
  for(int u : G[v])
    if(u != p)
      {
	dfs_cycle(u, v);
	cycle[v] += cycle[u];
      }
}

int root(int &v)
{
  if(dsuPar[v] == 0) return v;
  return dsuPar[v] = root(dsuPar[v]);
}

inline int lca(int &a, int &b)
{
  if(h[b] > h[a])
    swap(a, b);
  for(int i = 0; i < K; i++)
    if((1<<i) & (h[a] - h[b]))
      a = par[a][i];

  if(a == b)
    return a;

  for(int i = K-1; i >= 0; i--)
    if(par[a][i] != par[b][i])
      a = par[a][i], b = par[b][i];

  return par[a][0];
}

void dfs_reverse_cycle(int &v, int &p)
{
  h[v] = h[p] + 1;
  par[v][0] = p;
  for(int k = 1; k < K; k++)
    par[v][k] = par[par[v][k-1]][k-1];

  for(int u : G[v])
    if(u != p)
      {
	cycle[v] -= cycle[u];
	dfs_reverse_cycle(u, v);
      }
}

inline void merge(int &u, int &v)
{
  int ru = root(u), rv = root(v);
  if(rv == ru)
    {
      cycle[v]++;
      cycle[u]++;
      cycle[lca(u, v)] -= 2;
      return;
    }

  if(sz[ru] > sz[rv])
    swap(ru, rv), swap(u, v);

  // ru have on the smaller size of component
  dfs_cycle(ru, ru); // find the cycle values of ru component
  // update the path of a -> par[a][0] -> par[par[a][0]][0] -> .... -> ru

  vector<int> path = {u};
  while(par[path.back()][0]!=0)
    path.push_back(par[path.back()][0]);

  for(int i = path.size() - 1; i > 0; i--)
    cycle[path[i]] = cycle[path[i-1]];
  cycle[path[0]] = 0;

  dfs_reverse_cycle(u, v);

  G[u].push_back(v);
  G[v].push_back(u);
  
  dsuPar[ru] = rv; 
  sz[rv] += sz[ru]; 
  
}

int main()
{
  int n, m;
  scanf("%d %d",&n, &m);

  for(int i = 1; i <= n; i++)
    sz[i] = 1;

  int u, v;
  for(int i = 0; i < m; i++)
    {
      scanf("%d %d", &u, &v);
      merge(u, v);
    }

  for(int i = 1; i <= n; i++)
    if(par[i][0]==0)
      dfs_cycle(i, i);

  for(int i = 1; i <= n; i++)
    if(cycle[i] == 0 and par[i][0]!=0)
      printf("%d %d\n", i, par[i][0]);
  return 0;
}

Compilation message

pipes.cpp: In function 'int main()':
pipes.cpp:102:8: warning: ignoring return value of 'int scanf(const char*, ...)' declared with attribute 'warn_unused_result' [-Wunused-result]
  102 |   scanf("%d %d",&n, &m);
      |   ~~~~~^~~~~~~~~~~~~~~~
pipes.cpp:110:12: warning: ignoring return value of 'int scanf(const char*, ...)' declared with attribute 'warn_unused_result' [-Wunused-result]
  110 |       scanf("%d %d", &u, &v);
      |       ~~~~~^~~~~~~~~~~~~~~~~
# 결과 실행 시간 메모리 Grader output
1 Correct 1 ms 5464 KB Output is correct
2 Correct 2 ms 5468 KB Output is correct
# 결과 실행 시간 메모리 Grader output
1 Correct 5 ms 5468 KB Output is correct
2 Correct 5 ms 5468 KB Output is correct
# 결과 실행 시간 메모리 Grader output
1 Correct 152 ms 5468 KB Output is correct
2 Correct 149 ms 5644 KB Output is correct
# 결과 실행 시간 메모리 Grader output
1 Correct 269 ms 5844 KB Output is correct
2 Correct 316 ms 5972 KB Output is correct
# 결과 실행 시간 메모리 Grader output
1 Correct 447 ms 6492 KB Output is correct
2 Correct 398 ms 7528 KB Output is correct
# 결과 실행 시간 메모리 Grader output
1 Correct 650 ms 11428 KB Output is correct
2 Correct 583 ms 11420 KB Output is correct
# 결과 실행 시간 메모리 Grader output
1 Correct 988 ms 12492 KB Output is correct
2 Correct 971 ms 12784 KB Output is correct
# 결과 실행 시간 메모리 Grader output
1 Correct 1870 ms 14388 KB Output is correct
2 Correct 1593 ms 14596 KB Output is correct
# 결과 실행 시간 메모리 Grader output
1 Correct 1666 ms 14384 KB Output is correct
2 Correct 1656 ms 14428 KB Output is correct
# 결과 실행 시간 메모리 Grader output
1 Correct 2166 ms 13888 KB Output is correct
2 Correct 1982 ms 14548 KB Output is correct