結果
問題 | No.317 辺の追加 |
ユーザー |
![]() |
提出日時 | 2020-06-01 11:37:50 |
言語 | C++14 (gcc 13.3.0 + boost 1.87.0) |
結果 |
AC
|
実行時間 | 248 ms / 2,000 ms |
コード長 | 1,407 bytes |
コンパイル時間 | 1,060 ms |
コンパイル使用メモリ | 84,888 KB |
実行使用メモリ | 6,820 KB |
最終ジャッジ日時 | 2024-11-21 12:06:28 |
合計ジャッジ時間 | 11,150 ms |
ジャッジサーバーID (参考情報) |
judge4 / judge3 |
(要ログイン)
ファイルパターン | 結果 |
---|---|
sample | AC * 2 |
other | AC * 38 |
ソースコード
#include<iostream>#include<vector>#include<map>using namespace std;// 簡易UFstruct UF{vector<int> p;int n;UF(int siz){n = siz;p.resize(n, 0);for(int i = 0; i < n; i++) p[i] = i;}int parent(int x){if(p[x] != x) p[x] = parent(p[x]);return p[x];}bool same(int x, int y){return parent(x) == parent(y);}void unite(int x, int y){x = parent(x), y = parent(y);p[x] = y;}};// ナップサックで同じものをN個まで選べるときに// 2進数を使ってlog(N)で0~N個選ぶ場合を網羅するテクint main(){int n, x;cin >> n >> x;UF uf(n);while(x-- > 0){int u, v;cin >> u >> v;uf.unite(--u, --v);}vector<int> cnt(n, 0);for(int i = 0; i < n; i++) cnt[uf.parent(i)]++;map<int,int> m;for(int i = 0; i < n; i++){if(cnt[i]) m[cnt[i]]++;}vector<int> dp(n+1, 1<<30);dp[0] = 0;for(auto p : m){int res = p.second;for(int k = 0; res > 0; k++){int take = min(1<<k, res);res -= take;for(int j = n; j >= p.first*take; j--){dp[j] = min(dp[j], dp[j-p.first*take]+take);}}}for(int i = 1; i <= n; i++) cout << (dp[i]==1<<30 ? -1 : dp[i]-1) << endl;return 0;}