結果

問題 No.317 辺の追加
ユーザー moti
提出日時 2015-12-10 04:32:52
言語 C++11(廃止可能性あり)
(gcc 13.3.0)
結果
TLE  
実行時間 -
コード長 2,375 bytes
コンパイル時間 1,070 ms
コンパイル使用メモリ 117,060 KB
実行使用メモリ 11,648 KB
最終ジャッジ日時 2024-09-15 07:25:51
合計ジャッジ時間 5,984 ms
ジャッジサーバーID
(参考情報)
judge5 / judge3
このコードへのチャレンジ
(要ログイン)
ファイルパターン 結果
sample AC * 2
other AC * 2 TLE * 1 -- * 35
権限があれば一括ダウンロードができます

ソースコード

diff #

#include <iostream>
#include <algorithm>
#include <cmath>
#include <vector>
#include <complex>
#include <queue>
#include <deque>
#include <set>
#include <map>
#include <unordered_set>
#include <unordered_map>
#include <iomanip>
#include <assert.h>
#include <array>
#include <cstdio>
#include <cstring>
#include <random>
#include <functional>
#include <numeric>
#include <stack>
#include <bitset>

using namespace std;

#define REP(i,a,b) for(int i=a;i<(int)b;i++)
#define rep(i,n) REP(i,0,n)
#define all(c) (c).begin(), (c).end()
#define zero(a) memset(a, 0, sizeof a)
#define minus(a) memset(a, -1, sizeof a)
#define minimize(a, x) a = std::min(a, x)
#define maximize(a, x) a = std::max(a, x)

typedef long long ll;
int const inf = 1<<29;

struct UnionFind
{
  vector<int> rank;
  vector<int> rid;

  UnionFind(int n) {
    rank.resize(n);
    rid.assign(n, -1);
  }

  void unite(int u, int v) {
    u = root(u), v = root(v);
    if(u == v) { return ; }
    if(rank[u] < rank[v]) {
      rid[u] = v;
    }
    else {
      rid[v] = u;
      if(rank[u] == rank[v]) {
        rank[u]++;
      }
    }
  }

  bool same(int u, int v) {
    return root(u) == root(v);
  }

  int root(int x) {
    if(rid[x] < 0) return x;
    else return rid[x] = root(rid[x]);
  }
};

int main() {

  int N, M; cin >> N >> M;

  UnionFind uf(N);

  rep(i, M) {
    int u, v; cin >> u >> v; u--, v--;
    uf.unite(u, v);
  }

  map<int, int> mp;
  rep(i, N) {
    mp[uf.root(i)] ++;
  }
/*
  cout << "----------------\n";
  for(auto& e: mp) {
    cout << e.first << " " << e.second << endl;
  }
  cout << endl;
  cout << "----------------\n";
*/

  vector<int> nums;
  for(auto& e: mp) {
    nums.push_back(e.second);
  }

  vector<pair<int, bool>> dp(1);//(100001, {inf, false});
  dp[0] = {-1, true};

  for(auto& e: nums) {
    for(int i=dp.size()-1; i>=0; i--) {
      if(dp[i].second) {
        if(dp.size() <= i + e) {
          dp.resize(i + e + 1);
        }
        if(!dp[i + e].second || dp[i].first + 1 < dp[i + e].first) {
          dp[i + e] = {dp[i].first + 1, true};
        }
        if(dp.size() > 100001) { goto exi; }
      }
    }
  }

  exi:;

//  rep(i, 10) {  cout << i << " " << dp[i].first << " " << dp[i].second << endl; }

  REP(i, 1, N+1) {
    if(dp[i].second) {
      cout << dp[i].first << endl;
    }
    else {
      cout << -1 << endl;
    }
  }

  return 0;
}
0