結果
問題 | No.1320 Two Type Min Cost Cycle |
ユーザー |
|
提出日時 | 2020-12-02 20:54:20 |
言語 | C++17 (gcc 13.3.0 + boost 1.87.0) |
結果 |
CE
(最新)
AC
(最初)
|
実行時間 | - |
コード長 | 7,869 bytes |
コンパイル時間 | 535 ms |
コンパイル使用メモリ | 85,656 KB |
最終ジャッジ日時 | 2025-01-16 13:33:20 |
ジャッジサーバーID (参考情報) |
judge3 / judge3 |
(要ログイン)
コンパイルエラー時のメッセージ・ソースコードは、提出者また管理者しか表示できないようにしております。(リジャッジ後のコンパイルエラーは公開されます)
ただし、clay言語の場合は開発者のデバッグのため、公開されます。
ただし、clay言語の場合は開発者のデバッグのため、公開されます。
コンパイルメッセージ
main.cpp: In instantiation of ‘class RadixHeap<int>’: main.cpp:105:10: required from here main.cpp:17:36: error: ‘RadixHeap<T>::vq’ has incomplete type 17 | array<vector<TypeNode>,65> vq; | ^~ In file included from /usr/include/c++/13/bits/memory_resource.h:47, from /usr/include/c++/13/string:58, from /usr/include/c++/13/bits/locale_classes.h:40, from /usr/include/c++/13/bits/ios_base.h:41, from /usr/include/c++/13/ios:44, from /usr/include/c++/13/ostream:40, from /usr/include/c++/13/iostream:41, from main.cpp:1: /usr/include/c++/13/tuple:2019:45: note: declaration of ‘struct std::array<std::vector<std::pair<long long unsigned int, int>, std::allocator<std::pair<long long unsigned int, int> > >, 65>’ 2019 | template<typename _Tp, size_t _Nm> struct array; | ^~~~~ main.cpp: In function ‘int main()’: main.cpp:237:10: warning: ignoring return value of ‘int scanf(const char*, ...)’ declared with attribute ‘warn_unused_result’ [-Wunused-result] 237 | scanf("%d",&T); | ~~~~~^~~~~~~~~ main.cpp:238:10: warning: ignoring return value of ‘int scanf(const char*, ...)’ declared with attribute ‘warn_unused_result’ [-Wunused-result] 238 | scanf("%d%d",&N,&M); | ~~~~~^~~~~~~~~~~~~~ main.cpp:242:14: warning: ignoring return value of ‘int scanf(const char*, ...)’ declared with attribute ‘warn_unused_result’ [-Wunused-result] 242 | scanf("%d%d%d",&u,&v,&w); | ~~~~~^~~~~~~~~~~~~~~~~~~
ソースコード
#include <iostream>#include <vector>#include <cassert>#include <queue>#include <stack>#include <set>#include <algorithm>#include <map>using namespace std;/** @title RadixHeap - 64bit型非負整数heap* @docs md/heap/RadixHeap.md*/template<class T> class RadixHeap{using TypeNode = pair<unsigned long long, T>;array<vector<TypeNode>,65> vq;unsigned long long size_num;TypeNode last;inline int bit(unsigned long long a) {return a ? 64 - __builtin_clzll(a) : 0;}public:RadixHeap(T mini) : size_num(0), last(make_pair(0,mini)) {// do nothing}inline bool empty() {return size_num == 0;}inline size_t size(){return size_num;}inline void push(TypeNode x){++size_num;vq[bit(x.first^last.first)].push_back(x);}inline void emplace(unsigned long long key,T val){++size_num;vq[bit(key^last.first)].emplace_back(key,val);}inline TypeNode pop() {if(vq[0].empty()) {int i = 1;while(vq[i].empty()) ++i;last = *min_element(vq[i].begin(),vq[i].end());for(auto &p : vq[i]) vq[bit(p.first ^ last.first)].push_back(p);vq[i].clear();}--size_num;auto res = vq[0].back();vq[0].pop_back();return res;}};/** @title Graph* @docs md/graph/Graph.md*/template<class T> class Graph{private:const size_t N,H,W;public:vector<vector<pair<size_t,T>>> edges;Graph(const size_t N):H(-1),W(-1),N(N), edges(N) {}Graph(const size_t H, const size_t W):H(H),W(W),N(H*W), edges(H*W) {}inline void make_edge(size_t from, size_t to, T w) {edges[from].emplace_back(to,w);}//{from_y,from_x} -> {to_y,to_x}inline void make_edge(pair<size_t,size_t> from, pair<size_t,size_t> to, T w) {make_edge(from.first*W+from.second,to.first*W+to.second,w);}inline void make_bidirectional_edge(size_t from, size_t to, T w) {make_edge(from,to,w);make_edge(to,from,w);}inline void make_bidirectional_edge(pair<size_t,size_t> from, pair<size_t,size_t> to, T w) {make_edge(from.first*W+from.second,to.first*W+to.second,w);make_edge(to.first*W+to.second,from.first*W+from.second,w);}inline size_t size(){return N;}inline size_t idx(pair<size_t,size_t> yx){return yx.first*W+yx.second;}};/** @title MinimumDirectedClosedCircuit - 有向グラフの最小閉路検出* @docs md/graph/MinimumDirectedClosedCircuit.md*/template<class T> class MinimumDirectedClosedCircuit {//Tは整数型のみstatic_assert(std::is_integral<T>::value, "template parameter T must be integral type");Graph<T>& graph;vector<T> dist;vector<int> parent;size_t N;T inf;int last,root;private:T solve_impl() {T mini = inf;last = -1;RadixHeap<int> q(0);q.push({0,root});dist[root] = 0;while (q.size()) {auto top = q.pop();size_t curr = top.second;if(top.first > dist[curr]) continue;for(auto& edge:graph.edges[curr]){size_t next = edge.first;T w = edge.second;if(dist[next] > dist[curr]+w) {dist[next] = dist[curr] + w;parent[next] = curr;q.push({dist[next],next});}//根に返って来てるなら閉路候補if(next == root && mini > dist[curr]+w) {mini = dist[curr]+w;last = curr;}}}return mini;}public:MinimumDirectedClosedCircuit(Graph<T>& graph, T inf): graph(graph),N(graph.size()),dist(graph.size()),parent(graph.size()),inf(inf) {}//rootを含む最小閉路の集合を返す O(NlogN) 閉路がないときは空集合inline T solve(size_t rt){root = rt;//初期化for(int i = 0; i < N; ++i) dist[i] = inf, parent[i] = -1;//最小閉路の大きさを決めるT mini = solve_impl();return mini;}vector<int> restore() {vector<int> res;if(last == -1) return res;int curr = last;res.push_back(curr);while(curr != root) res.push_back(curr = parent[curr]);reverse(res.begin(),res.end());return res;}};/** @title MinimumUndirectedClosedCircuit - 無向グラフの最小閉路検出* @docs md/graph/MinimumUndirectedClosedCircuit.md*/template<class T> class MinimumUndirectedClosedCircuit {//Tは整数型のみstatic_assert(std::is_integral<T>::value, "template parameter T must be integral type");Graph<T> graph;vector<T> dist;vector<int> parent,label;size_t N;T inf;int last_l,last_r,root;private:void solve_impl() {RadixHeap<int> q(0);q.push({0,root});dist[root] = 0;while (q.size()) {auto top = q.pop();size_t curr = top.second;if(top.first > dist[curr]) continue;for(auto& edge:graph.edges[curr]){size_t next = edge.first;T w = edge.second;if(parent[curr] == next) continue;if(dist[next] > dist[curr] + w) {dist[next] = dist[curr] + w;parent[next] = curr;label[next] = (curr==root?next:label[curr]);q.push({dist[next],next});}}}}T solve_cycle() {T mini = inf;last_l=-1,last_r=-1;for(int l=0;l<N;++l) {if(l==root) continue;for(auto& edge:graph.edges[l]){int r = edge.first;T w = edge.second;if(mini <= dist[l] + dist[r] + w) continue;if( (r==root && l!=label[l]) || (r!=root && label[l]!=label[r]) ) {mini = dist[l] + dist[r] + w;last_l = l;last_r = r;}}}return mini;}public:MinimumUndirectedClosedCircuit(Graph<T>& graph, T inf): graph(graph),N(graph.size()),dist(graph.size()),parent(graph.size()),label(graph.size()),inf(inf) {}//rootを含む最小閉路の集合を返す O(NlogN) 閉路がないときは空集合inline T solve(size_t rt){root = rt;//初期化for(int i = 0; i < N; ++i) dist[i] = inf, parent[i] = -1;solve_impl();T mini=solve_cycle();return mini;}//復元vector<int> restore() {stack<int> s;queue<int> q;vector<int> res;if(last_l != -1 && last_r != -1){for(int curr = last_l; curr != -1; curr = parent[curr]) s.push(curr);for(int curr = last_r; curr != root; curr = parent[curr]) q.push(curr);while(s.size()) res.push_back(s.top()) ,s.pop();while(q.size()) res.push_back(q.front()),q.pop();}return res;}};template <class T> void chmin(T& a, const T b){a=min(a,b);}int main(void) {int T,N,M;scanf("%d",&T);scanf("%d%d",&N,&M);Graph<long long> graph(N);while(M--) {int u,v,w;scanf("%d%d%d",&u,&v,&w);u--,v--;if(T) graph.make_edge(u,v,w);else graph.make_bidirectional_edge(u,v,w);}long long inf = 1e15;long long ans = inf;if(T) {MinimumDirectedClosedCircuit<long long> mdcc(graph,inf);for(int i=0;i<N;++i) chmin(ans,mdcc.solve(i));}else {MinimumUndirectedClosedCircuit<long long> mucc(graph,inf);for(int i=0;i<N;++i) chmin(ans,mucc.solve(i));}if(ans == inf) ans = -1;printf("%lld\n",ans);}