結果
問題 | No.317 辺の追加 |
ユーザー |
![]() |
提出日時 | 2015-12-11 12:42:14 |
言語 | C++11(廃止可能性あり) (gcc 13.3.0) |
結果 |
AC
|
実行時間 | 123 ms / 2,000 ms |
コード長 | 2,170 bytes |
コンパイル時間 | 940 ms |
コンパイル使用メモリ | 108,116 KB |
実行使用メモリ | 5,376 KB |
最終ジャッジ日時 | 2024-09-15 07:56:13 |
合計ジャッジ時間 | 5,685 ms |
ジャッジサーバーID (参考情報) |
judge4 / judge2 |
(要ログイン)
ファイルパターン | 結果 |
---|---|
sample | AC * 2 |
other | AC * 38 |
ソースコード
#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 union_find {vector<int> rank_;vector<int> size_;vector<int> rid_;union_find(int n) { rank_.resize(n); rid_.assign(n, -1); size_.resize(n, 1); }void unite(int u, int v) {u = root(u), v = root(v);if(u == v) { return; }size_[u] = size_[v] = size_[u] + size_[v];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 operator[](int x) { return root(x); }int size_of(int x) { return size_[x]; }};int main() {int N, M; cin >> N >> M;union_find uf(N);rep(i, M) {int u, v; cin >> u >> v; u--, v--;uf.unite(u, v);}vector<int> sizecnt(N + 1);rep(i, N) {if(uf[i] == i) {sizecnt[uf.size_of(uf[i])] ++;}}vector<int> dp(N + 1, inf);dp[0] = 0;// programming contest challenge book p.303int W = 0;for(int i = 1; i <= N; i++) {int num = sizecnt[i];for(int k = 1; num > 0; k *= 2) {int mul = min(k, num);num -= mul;W += i * mul;for(int j = W; j >= i * mul; j--) {if(dp[j - i * mul] >= inf) { continue; }minimize(dp[j], dp[j - i * mul] + mul);}}}for(int i = 1; i <= N; i++) {printf("%d\n", dp[i] == inf ? -1 : dp[i] - 1);}return 0;}