結果

問題 No.3345 Reducible Sequence
コンテスト
ユーザー tnakao0123
提出日時 2025-11-15 17:45:57
言語 C++17
(gcc 13.3.0 + boost 1.87.0)
結果
AC  
実行時間 167 ms / 2,000 ms
コード長 2,865 bytes
コンパイル時間 984 ms
コンパイル使用メモリ 75,028 KB
実行使用メモリ 13,072 KB
最終ジャッジ日時 2025-11-15 17:46:00
合計ジャッジ時間 2,936 ms
ジャッジサーバーID
(参考情報)
judge3 / judge4
このコードへのチャレンジ
(要ログイン)
ファイルパターン 結果
sample AC * 3
other AC * 26
権限があれば一括ダウンロードができます
コンパイルメッセージ
main.cpp: In function ‘int main()’:
main.cpp:123:8: warning: ignoring return value of ‘int scanf(const char*, ...)’ declared with attribute ‘warn_unused_result’ [-Wunused-result]
  123 |   scanf("%d", &n);
      |   ~~~~~^~~~~~~~~~
main.cpp:124:36: warning: ignoring return value of ‘int scanf(const char*, ...)’ declared with attribute ‘warn_unused_result’ [-Wunused-result]
  124 |   for (int i = 0; i < n; i++) scanf("%d", as + i);
      |                               ~~~~~^~~~~~~~~~~~~~

ソースコード

diff #

/* -*- coding: utf-8 -*-
 *
 * 3345.cc:  No.3345 Reducible Sequence - yukicoder
 */

#include<cstdio>
#include<vector>
#include<queue>
#include<algorithm>
#include<utility>

using namespace std;

/* constant */

const int MAX_N = 5000;
const int MAX_A = 5000;
const int INF = 1 << 30;

/* typedef */

template <typename T>
struct MaxFlow {
  using pii = pair<int,int>;
  using vpii = vector<pii>;
  using vvpii = vector<vpii>;

  int n, m;
  vvpii nbrs;
  T inf, max_flow;
  vpii prvs;
  vector<T> minfs, caps, flows;

  MaxFlow(int _n, T _inf): n(_n), m(0), inf(_inf) {
    nbrs.assign(n, vpii());
    minfs.assign(n, 0);
    prvs.assign(n, {-1, -1});
    caps.clear(), flows.clear();
    max_flow = 0;
  }

  int addedges(int u, int v, T c) {
    // edge[m]: u -> v, cap=c
    nbrs[u].push_back({v, m});
    caps.push_back(c); flows.push_back(0);

    // edge[m + 1]: v -> u, cap=0
    nbrs[v].push_back({u, m + 1});
    caps.push_back(0); flows.push_back(0);

    m += 2;
    return m;
  }
  
  T flow(int st, int gl, bool cont = false) {
    if (! cont) {
      fill(flows.begin(), flows.end(), 0);
      max_flow = 0;
    }

    for (;;) {
      //printf("max_flow = %d, limit = %d\n", max_flow, limit);

      fill(prvs.begin(), prvs.end(), pii(-1, -1));
      prvs[st] = {st, -1};
      minfs[st] = inf;

      queue<int> q;
      q.push(st);

      while (! q.empty()) {
	int u = q.front(); q.pop();
	if (u == gl) break;

	for (auto [v, ei]: nbrs[u]) {
	  T vc = caps[ei] - flows[ei];
	  if (prvs[v].first < 0 && vc > 0) {
	    prvs[v] = {u, ei};
	    minfs[v] = (minfs[u] < vc) ? minfs[u] : vc;
	    q.push(v);
	  }
	}
      }
      if (prvs[gl].first < 0) break;

      T min_flow = minfs[gl];
      for (int j = gl; j != st;) {
	auto [i, ei] = prvs[j];
	flows[ei] += min_flow;
	flows[ei ^ 1] -= min_flow;
	j = i;
      }
      max_flow += min_flow;
    }

    return max_flow;
  }
};

/*
int main() {
  const int INF = 1 << 30;
  MaxFlow<int> mf(3, INF);
  mf.addedges(0, 1, 1);
  mf.addedges(1, 2, 3);
  mf.addedges(0, 2, 1);
  int f = mf.flow(0, 2);
  printf("f=%d\n", f);
  return 0;
}
*/

/* global variables */

int as[MAX_N];

/* subroutines */

/* main */

int main() {
  int n;
  scanf("%d", &n);
  for (int i = 0; i < n; i++) scanf("%d", as + i);

  int st = n * 2, gl = st + 1, gn = gl + 1;
  MaxFlow<int> mf(gn, INF);

  for (int i = 0; i < n; i++) mf.addedges(st, i, 0);
  for (int i = 0; i < n; i++)
    for (int p = 1; p <= n && p * p <= as[i]; p++)
      if (as[i] % p == 0) {
	int q = as[i] / p;
	mf.addedges(p - 1, n + i, 1);
	if (q <= n && q != p) mf.addedges(q - 1, n + i, 1);
      }
  for (int i = 0; i < n; i++) mf.addedges(n + i, gl, 1);

  int m = 0;
  for (bool cont = false; m < n; m++, cont = true) {
    mf.caps[m * 2] = 1;
    int f = mf.flow(st, gl, cont);
    if (f <= m) break;
  }

  printf("%d\n", m);
  
  return 0;
}

0