結果

問題 No.317 辺の追加
ユーザー vjudge1
提出日時 2025-01-19 16:14:20
言語 C++14
(gcc 13.3.0 + boost 1.87.0)
結果
WA  
実行時間 -
コード長 1,962 bytes
コンパイル時間 1,365 ms
コンパイル使用メモリ 163,092 KB
実行使用メモリ 6,824 KB
最終ジャッジ日時 2025-01-19 16:14:26
合計ジャッジ時間 5,004 ms
ジャッジサーバーID
(参考情報)
judge4 / judge2
このコードへのチャレンジ
(要ログイン)
ファイルパターン 結果
sample AC * 2
other AC * 19 WA * 19
権限があれば一括ダウンロードができます

ソースコード

diff #

#include <bits/stdc++.h>
using namespace std;
const int N = 1e5 + 5;

int n, m, f[N], a[N], tot, p[N], dp[N];
int cnt[N];

int find(int x){
	if(x == f[x])
		return x;
	else
		return f[x] = find(f[x]);
}

int main(){
	ios::sync_with_stdio(0), cin.tie(0), cout.tie(0);
	cin >> n >> m;
	for(int i = 1; i <= n; i++)
		f[i] = i;
	for(int i = 1; i <= m; i++){
		int x, y;
		cin >> x >> y;
		int fx = find(x), fy = find(y);
		if(fx == fy)
			continue;
		else{
			if(p[fx] == 0){
				p[fx] = p[fy] = ++tot;
				a[tot] = 2;
				f[fy] = fx;
			}
			else{
				a[p[fx]]++;
				p[fy] = p[fx];
				f[fy] = fx;
			}
		}
//		cout << "qwq " << fx << " " << fy << "\n";
	}
	for(int i = 1; i <= n; i++){
		int ff = find(i);
		if(p[ff] == 0){
			p[ff] = ++tot;
			a[tot]++;
		}
	}
//	for(int i = 1; i <= tot; i++)
//		cout << a[i] << " ";
//	cout << "\n";
//	for(int i = 1; i <= n; i++){
//		cout << p[i] << " ";
//	}
//	sort(a + 1, a + 1 + tot);
	for(int i = 1; i <= tot; i++)
		cnt[a[i]]++;
	memset(dp, 0x3f, sizeof(dp));
//	for(int i = 1; i <= tot; i++)
//		dp[a[i]] = 0;	
//	for(int i = 1; i <= N; i++){
//		for(int j = 1; j <= tot && i - a[j] >= 0; j++){
//			dp[i] = min(dp[i], dp[i - a[j]] + 1);
//		}
//	}
//	for(int i = 1; i <= tot; i++){
//		for(int j = 10; j >= a[i]; j--){
//			if(dp[j - a[i]] == 0 && dp[j] != 0x3f3f3f3f)
//				continue;
//			if(j == 6)
//				cout << i << " " << j << " " << dp[j] << " " << a[i] << " " << dp[j - a[i]] << "\n";
//			dp[j] = min(dp[j], dp[j - a[i]] + 1); 
//			cout << i << " " << j << " " << dp[j] << " " << a[i] << " " << dp[j - a[i]] << "\n";	
//		}
//	}
	dp[0] = 0;
	for (int i = 1; i <= n; i++){
		for (int k = 1; cnt[i]; k <<= 1){
			int num = min(cnt[i], k);
			for (int j = N - num * i; j >= 0; j--){
				int nj = j + num * i;
				dp[nj] = min(dp[nj], dp[j] + num);
			}
			cnt[i] -= num;
		}
	}
	for(int i = 1; i <= n; i++){
		if(dp[i] == 0x3f3f3f3f)
			cout << -1 << "\n";
		else
			cout << dp[i] - 1 << "\n";
	}
	return 0;
}
0