Submission #62552796
Source Code Expand
Copy
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
הההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההה
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
#include <iostream>
#include <vector>
#include <map>
#include <algorithm>
#include <tuple>
using namespace std;
#define REP(i,n) for (int i=0;i<n;i++)
#define ALL(x) (x).begin(), (x).end()
using pii = pair<int,int>;
struct E {
int id, a, b; // a,b は 0-indexed
};
struct UnionFind {
vector<int> par, rank, siz;
UnionFind(int n) : par(n,-1), rank(n,0), siz(n,1) { }
int root(int x) { return par[x] < 0 ? x : par[x] = root(par[x]); }
bool unite(int x, int y) {
int rx=root(x), ry=root(y);
if(rx==ry)return false;
if(rank[rx]<rank[ry]) swap(rx,ry);
par[ry]=rx;
if(rank[rx]==rank[ry]) rank[rx]++;
siz[rx]+=siz[ry];
return true;
}
};
int main(){
ios::sync_with_stdio(false);
cin.tie(nullptr);
int N, M, cnt=0;
cin >> N >> M;
vector<int> A(M), B(M);
map<pii,int> mp;
UnionFind uf(N);
vector<E> edge; // spanning forest に使われなかったケーブル(冗長ケーブル)
REP(i, M) {
cin >> A[i] >> B[i];
A[i]--,B[i]--;
if(!mp.count({A[i],B[i]}) && A[i]!=B[i]){
if(uf.unite(A[i],B[i])) cnt++;
else edge.push_back({i, A[i], B[i]});
} else {
edge.push_back({i, A[i], B[i]});
}
mp[{A[i],B[i]}]=1;
}
// 各サーバーの連結成分代表
vector<int> R;
REP(i,N) R.push_back(uf.root(i));
sort(ALL(R));
R.erase(unique(ALL(R)), R.end());
int compCount = R.size();
if(compCount==1){
cout << 0 << "\n";
return 0;
}
// 各成分毎に冗長ケーブルをまとめる
map<int, vector<E>> compRed;
for(auto &e : edge){
int r = uf.root(e.a);
compRed[r].push_back(e);
}
// 各成分の冗長ケーブル数を数え、メイン成分としてケーブルを最も持つ成分を選ぶ
int mainRep = R[0];
int maxCount = compRed[mainRep].size();
for(auto r : R){
if((int)compRed[r].size() > maxCount){
maxCount = compRed[r].size();
mainRep = r;
}
}
// 各成分と mainRep を接続する操作 (操作回数は compCount - 1)
vector<tuple<int,int,int>> ops; // (ケーブル番号, 変更前, 変更後) (0-indexed, 後で+1して出力)
for(auto r : R){
if(r==mainRep) continue;
// まず対象成分 r 側の冗長ケーブルがあるなら利用
if(!compRed[r].empty()){
E e = compRed[r].back();
compRed[r].pop_back();
// e は r 内のケーブル (e.a と e.b は r)
// 変更前のサーバーは r, 変更後は mainRep, 結果として (mainRep, r) となる
ops.push_back({e.id, r, mainRep});
}
// なければ mainRep 側の冗長ケーブルを使う
else if(!compRed[mainRep].empty()){
E e = compRed[mainRep].back();
compRed[mainRep].pop_back();
// e は mainRep 内のケーブル (e.a と e.b は mainRep)
// 変更前のサーバーは mainRep, 変更後は r, 結果として (mainRep, r) となる
ops.push_back({e.id, mainRep, r});
}
// どちらにも無い場合は,本来は存在しない(問題設定より解は必ず存在する)
}
cout << ops.size() << "\n";
for(auto &op : ops){
int cable, before, after;
tie(cable, before, after) = op;
cout << cable+1 << " " << before+1 << " " << after+1 << "\n";
}
return 0;
}
Submission Info
| Submission Time |
|
| Task |
E - Cables and Servers |
| User |
una_o0 |
| Language |
C++ 20 (gcc 12.2) |
| Score |
0 |
| Code Size |
3673 Byte |
| Status |
WA |
| Exec Time |
202 ms |
| Memory |
32724 KiB |
Judge Result
| Set Name |
Sample |
All |
| Score / Max Score |
0 / 0 |
0 / 450 |
| Status |
|
|
| Set Name |
Test Cases |
| Sample |
sample_01.txt, sample_02.txt, sample_03.txt |
| All |
random_01.txt, random_02.txt, random_03.txt, random_04.txt, random_05.txt, random_06.txt, random_07.txt, random_08.txt, random_09.txt, random_10.txt, random_11.txt, random_12.txt, random_13.txt, random_14.txt, random_15.txt, random_16.txt, random_17.txt, random_18.txt, random_19.txt, sample_01.txt, sample_02.txt, sample_03.txt |
| Case Name |
Status |
Exec Time |
Memory |
| random_01.txt |
WA |
69 ms |
14396 KiB |
| random_02.txt |
AC |
60 ms |
11844 KiB |
| random_03.txt |
WA |
6 ms |
4580 KiB |
| random_04.txt |
WA |
1 ms |
3648 KiB |
| random_05.txt |
AC |
105 ms |
18352 KiB |
| random_06.txt |
AC |
22 ms |
7720 KiB |
| random_07.txt |
WA |
8 ms |
4992 KiB |
| random_08.txt |
WA |
1 ms |
3420 KiB |
| random_09.txt |
WA |
77 ms |
15328 KiB |
| random_10.txt |
AC |
41 ms |
9076 KiB |
| random_11.txt |
WA |
111 ms |
19828 KiB |
| random_12.txt |
WA |
1 ms |
3492 KiB |
| random_13.txt |
AC |
129 ms |
20520 KiB |
| random_14.txt |
AC |
128 ms |
20536 KiB |
| random_15.txt |
AC |
127 ms |
20456 KiB |
| random_16.txt |
AC |
129 ms |
20580 KiB |
| random_17.txt |
AC |
202 ms |
31508 KiB |
| random_18.txt |
AC |
135 ms |
32724 KiB |
| random_19.txt |
AC |
2 ms |
3628 KiB |
| sample_01.txt |
WA |
1 ms |
3524 KiB |
| sample_02.txt |
AC |
1 ms |
3520 KiB |
| sample_03.txt |
AC |
1 ms |
3512 KiB |