結果
問題 | No.748 yuki国のお財布事情 |
ユーザー |
![]() |
提出日時 | 2021-05-26 06:28:53 |
言語 | C++14 (gcc 13.3.0 + boost 1.87.0) |
結果 |
AC
|
実行時間 | 80 ms / 2,000 ms |
コード長 | 5,174 bytes |
コンパイル時間 | 4,287 ms |
コンパイル使用メモリ | 245,584 KB |
実行使用メモリ | 16,276 KB |
最終ジャッジ日時 | 2024-10-15 03:44:03 |
合計ジャッジ時間 | 6,054 ms |
ジャッジサーバーID (参考情報) |
judge5 / judge2 |
(要ログイン)
ファイルパターン | 結果 |
---|---|
sample | AC * 3 |
other | AC * 26 |
ソースコード
// #pragma GCC optimize ("O3")// #pragma GCC target("avx512f")// #pragma GCC optimize("unroll-loops")#ifndef ONLINE_JUDGE#define _GLIBCXX_DEBUG#endif#include<bits/stdc++.h>#include<atcoder/all>using namespace std;using namespace atcoder;#define rep(i, n) for (ll i = 0; i < (ll)(n); i++)#define bit(n,k) (((ll)n>>(ll)k)&1) /*nのk bit目*/#define pb push_back#define pf push_front#define fi first#define se second#define eb emplace_back#define endl '\n'#define SZ(x) ((ll)(x).size())#define all(x) (x).begin(),(x).end()#define rall(x) (x).rbegin(),(x).rend()#define debug(v) cout<<#v<<":";for(auto x:v){cout<<x<<' ';}cout<<endl;#define PI 3.14159265359const double eps = 1e-12;const long long INF= (long long)1e18+20;const int inf= 1010101010;typedef double D; // 座標値の型。doubleかlong doubleを想定typedef complex<D> Point; // Pointtypedef long long ll;typedef vector<ll> vl;typedef vector<vl>vvl;typedef vector<vvl>vvvl;typedef vector<vvvl>vvvvl;typedef vector<vvvvl>vvvvvl;typedef pair<ll,ll> P;typedef tuple<ll,ll,ll> T;template<class T> using minpq=priority_queue<T,vector<T>,greater<T>>;const ll MOD=1000000007LL;// const ll MOD=998244353LL;// using mint=modint998244353;// using mint=modint1000000007;using mint=modint;const ll mod=MOD;string abc="abcdefghijklmnopqrstuvwxyz";string ABC="ABCDEFGHIJKLMNOPQRSTUVWXYZ";vl dx={0,0,1,-1,1,1,-1,-1};vl dy={1,-1,0,0,-1,1,-1,1};template<class T> vector<T> make_vec(size_t a) { return vector<T>(a); }template<class T, class... Ts> auto make_vec(size_t a, Ts... ts) {return vector<decltype(make_vec<T>(ts...))>(a, make_vec<T>(ts...));}template<class T>bool chmax(T &a,const T &b){if(a<b){a=b;return true;}return false;}template<class T>bool chmin(T &a,const T &b){if(b<a){a=b;return true;}return false;}typedef vector<mint>vm;typedef vector<vm>vvm;typedef vector<vvm>vvvm;ll modpow(ll a, ll n,ll mod=MOD) {ll res = 1;while (n > 0) {if (n & 1) res = res * a % mod;a = a * a % mod;n >>= 1;}return res;}/* UnionFind:素集合系管理の構造体(union by rank)isSame(x, y): x と y が同じ集合にいるか。 計算量はならし O(α(n))unite(x, y): x と y を同じ集合にする。計算量はならし O(α(n))*/struct UnionFind { // The range of node number is u 0 v n-1vector<int> rank, parents;UnionFind() {}UnionFind(int n) { // make n trees.rank.resize(n, 0);parents.resize(n, 0);for (int i = 0; i < n; i++) {makeTree(i);}}void makeTree(int x) {parents[x] = x; // the parent of x is xrank[x] = 0;}bool isSame(int x, int y) { return findRoot(x) == findRoot(y); }void unite(int x, int y) {x = findRoot(x);y = findRoot(y);if (rank[x] > rank[y]) {parents[y] = x;} else {parents[x] = y;if (rank[x] == rank[y]) {rank[y]++;}}}int findRoot(int x) {if (x != parents[x]) parents[x] = findRoot(parents[x]);return parents[x];}};// 辺の定義struct Edge {long long u;long long v;long long cost;};bool comp_e(const Edge &e1, const Edge &e2) { return e1.cost < e2.cost; } // 辺を直接比較するための関数/* Kruskal :クラスカル法で minimum spanning tree を求める構造体入力: 辺のvector, 頂点数V最小全域木の重みの総和: sum計算量: O(|E|log|V|)*/struct Kruskal {UnionFind uft;long long sum; // 最小全域木の重みの総和vector<Edge> edges;int V;Kruskal(const vector<Edge> &edges_, int V_) : edges(edges_), V(V_) { init(); }void init() {sort(edges.begin(), edges.end(), comp_e); // 辺の重みでソートuft = UnionFind(V);sum = 0;for (auto e : edges) {if (!uft.isSame(e.u, e.v)) { // 閉路にならなければ加えるuft.unite(e.u, e.v);sum += e.cost;}}}};int main(){ios::sync_with_stdio(false);std::cin.tie(nullptr);cout << fixed << setprecision(12);/*--------------------------------*/int n,m,k;cin>>n>>m>>k;int V;vector<Edge> edges;ll sum=0;dsu uf(n);vl a(m),b(m),c(m);ll ans=0;for (int i = 0; i < m; i++) {cin>>a[i]>>b[i]>>c[i];ans+=c[i];a[i]--,b[i]--;}rep(i,k){ll e;cin>>e;e--;ans-=c[e];uf.merge(a[e],b[e]);}set<int>st;rep(i,n){// cout<<uf.leader(i)<<" ";st.insert(uf.leader(i));}// cout<<endl;V=st.size();vector<int>num(n);int idx=0;for(auto x:st){num[x]=idx;idx++;}// debug(num);for(int i=0;i<m;i++){if(uf.leader(a[i])==uf.leader(b[i]))continue;edges.pb({num[uf.leader(a[i])],num[uf.leader(b[i])],c[i]});}Kruskal krs(edges, V);// cout<<ans<<" "<<krs.sum<<endl;cout << ans-krs.sum << endl;return 0;}