結果
問題 | No.748 yuki国のお財布事情 |
ユーザー | puni_kyopro |
提出日時 | 2018-12-02 16:57:23 |
言語 | C++11 (gcc 11.4.0) |
結果 |
AC
|
実行時間 | 150 ms / 2,000 ms |
コード長 | 3,593 bytes |
コンパイル時間 | 687 ms |
コンパイル使用メモリ | 75,808 KB |
実行使用メモリ | 9,740 KB |
最終ジャッジ日時 | 2024-07-01 05:23:54 |
合計ジャッジ時間 | 3,065 ms |
ジャッジサーバーID (参考情報) |
judge1 / judge3 |
(要ログイン)
テストケース
テストケース表示入力 | 結果 | 実行時間 実行使用メモリ |
---|---|---|
testcase_00 | AC | 3 ms
5,248 KB |
testcase_01 | AC | 3 ms
5,376 KB |
testcase_02 | AC | 3 ms
5,376 KB |
testcase_03 | AC | 3 ms
5,376 KB |
testcase_04 | AC | 3 ms
5,376 KB |
testcase_05 | AC | 3 ms
5,376 KB |
testcase_06 | AC | 3 ms
5,376 KB |
testcase_07 | AC | 2 ms
5,376 KB |
testcase_08 | AC | 3 ms
5,376 KB |
testcase_09 | AC | 3 ms
5,376 KB |
testcase_10 | AC | 3 ms
5,376 KB |
testcase_11 | AC | 3 ms
5,376 KB |
testcase_12 | AC | 3 ms
5,376 KB |
testcase_13 | AC | 17 ms
5,496 KB |
testcase_14 | AC | 30 ms
6,084 KB |
testcase_15 | AC | 21 ms
5,888 KB |
testcase_16 | AC | 56 ms
7,216 KB |
testcase_17 | AC | 111 ms
9,008 KB |
testcase_18 | AC | 133 ms
9,420 KB |
testcase_19 | AC | 150 ms
9,740 KB |
testcase_20 | AC | 134 ms
9,696 KB |
testcase_21 | AC | 129 ms
9,344 KB |
testcase_22 | AC | 3 ms
5,376 KB |
testcase_23 | AC | 3 ms
5,376 KB |
testcase_24 | AC | 3 ms
5,376 KB |
testcase_25 | AC | 101 ms
8,944 KB |
testcase_26 | AC | 124 ms
9,092 KB |
testcase_27 | AC | 119 ms
9,072 KB |
testcase_28 | AC | 103 ms
9,576 KB |
ソースコード
#include<iostream> #include<vector> #include<algorithm> #include<cctype> #include<utility> #include<string> #include<cmath> #include <numeric> #include<set> #define REP(i, n) for(int i = 0;i < n;i++) #define REPR(i, n) for(int i = n;i >= 0;i--) #define FOR(i, m, n) for(int i = m;i < n;i++) #define FORR(i, m, n) for(int i = m;i >= n;i--) #define SORT(v, n) sort(v, v+n); #define VSORT(v) sort(v.begin(), v.end()); #define llong long long #define pb(a) push_back(a) #define INF 999999999 using namespace std; typedef pair<int, int> P; typedef pair<llong, llong> LP; typedef pair<int, P> PP; typedef pair<llong, LP> LPP; typedef long long int ll; #define ARRAY_MAX 100005 vector<ll> par(ARRAY_MAX);//親 vector<ll> ran(ARRAY_MAX);//木の深さ bool used[ARRAY_MAX];//使ったかどうか typedef struct edge{ ll num; ll u; ll v; ll cost; }EDGE; bool comp(const EDGE& e1,const EDGE& e2){ return e1.cost < e2.cost; } //n要素で初期化 void init(ll n){ for(ll i = 0;i < n;i++){ par[i] = i;/*各ノードに番号を振る,この時par[x]=xとなる時は木の根となる*/ ran[i] = 0;/*各ノード自体の高さは0*/ } } //木の根を求める ll find(ll x){ if(par[x] == x){ return x;/*根ならそのノードの番号を返す*/ }else{ return par[x] = find(par[x]);/*根でないならさらにノードの根を探す*/ } } //xとyの属する集合を併合する void unite(ll x,ll y){ x = find(x);//xの根の番号を探す y = find(y);//yの根の番号を探す if(x == y){//一致すればつながっている return; } if(ran[x] < ran[y]){//xの高さが低いなら高いほうにつなぐ、そして高さは大きい方(y)になる par[x] = y; }else{ par[y] = x;//yの高さが低いなら高いほうにつなぐ、そして高さは大きいほう(x)になる if(ran[x] == ran[y]){//高さが一致しているなら併合の高さは1増える ran[x]++; } } } //xとyが同じ集合に属するか判定 bool same(ll x,ll y){ return find(x) == find(y);//同じ集合なら1、違うなら0が返る } ll kruskal(ll n,ll count,vector<EDGE>& es,ll ans){ sort(es.begin(),es.end(),comp);//小さいほうから ll res = ans; for(ll i = 0;i < count;i++){ EDGE e = es[i]; if(used[e.num] == true){ //すでに数えた continue; } if(!same(e.u,e.v)){ //つなぐ unite(e.u,e.v); used[e.num] = true; res += e.cost; } } return res; } /*最小全域木をクラスカル法で実装*/ int main(){ ll n,m,k; cin >> n >> m >> k; vector<EDGE> es; ll count = 0; ll a,b,c; ll sum = 0;//全経路の合計コスト ll use[k]; ll ans = 0; init(n); for(ll i = 0;i < m;i++){ cin >> a >> b >> c; a--; b--; sum += c; EDGE e; e.num = i; e.u = a; e.v = b; e.cost = c;/*昇順ソート済み*/ es.push_back(e); } //mapの作成 REP(i,ARRAY_MAX){ used[i] = false; } //閉鎖できない経路を先につないでおく for(ll i = 0;i < k;i++){ cin >> use[i]; use[i]--; unite(es[use[i]].u,es[use[i]].v);//先につないでおく ans += es[use[i]].cost; used[use[i]] = true; } ans = kruskal(n,m,es,ans);//最小全域木作成 cout << sum - ans << endl; return 0; }