結果
| 問題 |
No.2914 正閉路検出
|
| コンテスト | |
| ユーザー |
SnowBeenDiding
|
| 提出日時 | 2024-10-04 21:56:05 |
| 言語 | C++23 (gcc 13.3.0 + boost 1.87.0) |
| 結果 |
WA
|
| 実行時間 | - |
| コード長 | 4,150 bytes |
| コンパイル時間 | 5,907 ms |
| コンパイル使用メモリ | 332,436 KB |
| 実行使用メモリ | 25,788 KB |
| 最終ジャッジ日時 | 2024-10-04 21:56:26 |
| 合計ジャッジ時間 | 16,540 ms |
|
ジャッジサーバーID (参考情報) |
judge1 / judge5 |
(要ログイン)
| ファイルパターン | 結果 |
|---|---|
| other | AC * 16 WA * 39 |
ソースコード
#include <atcoder/all>
#include <bits/stdc++.h>
#define rep(i, a, b) for (ll i = (ll)(a); i < (ll)(b); i++)
using namespace atcoder;
using namespace std;
typedef long long ll;
struct UnionFindWeight {
vector<ll> par;
vector<ll> rank;
vector<ll> diff_weight;
UnionFindWeight(ll n = 1, ll SUM_UNITY = 0) { reset(n, SUM_UNITY); }
void reset(ll n = 1, ll SUM_UNITY = 0) {
par.resize(n);
rank.resize(n);
diff_weight.resize(n);
for (ll i = 0; i < n; ++i)
par[i] = i, rank[i] = 0, diff_weight[i] = SUM_UNITY;
}
ll root(ll x) {
if (par[x] == x) {
return x;
} else {
ll r = root(par[x]);
diff_weight[x] += diff_weight[par[x]];
return par[x] = r;
}
}
ll weight(ll x) {
root(x);
return diff_weight[x];
}
bool same(ll x, ll y) { return root(x) == root(y); }
bool unite(ll x, ll y, ll w) { // x ----(距離 w)---- y
w += weight(x);
w -= weight(y);
x = root(x);
y = root(y);
if (x == y)
return false;
if (rank[x] < rank[y])
swap(x, y), w = -w;
if (rank[x] == rank[y])
++rank[x];
par[y] = x;
diff_weight[y] = w;
return true;
}
ll dist(ll x, ll y) { return weight(y) - weight(x); }
};
template <typename T> struct Graph {
struct edge {
int to;
T cost;
};
int N;
vector<vector<edge>> G;
vector<T> dist;
vector<int> prever;
Graph(int n) { init(n); }
T inf() {
if (is_same_v<T, int>)
return 1e9;
else
return 1e18;
}
T zero() { return T(0); }
void init(int n) {
N = n;
G.resize(N);
dist.resize(N, inf());
}
void add_edge(int s, int t, T cost) {
edge e;
e.to = t, e.cost = cost;
G[s].push_back(e);
}
void dijkstra(int s) {
rep(i, 0, N) dist[i] = inf();
prever = vector<int>(N, -1);
dist[s] = zero();
priority_queue<pair<T, int>, vector<pair<T, int>>,
greater<pair<T, int>>>
q;
q.push({zero(), s});
while (!q.empty()) {
int now;
T nowdist;
tie(nowdist, now) = q.top();
q.pop();
if (dist[now] < nowdist)
continue;
for (auto e : G[now]) {
T nextdist = nowdist + e.cost; // 次の頂点への距離
if (dist[e.to] > nextdist) {
prever[e.to] = now;
dist[e.to] = nextdist;
q.push({dist[e.to], e.to});
}
}
}
}
vector<int> get_path(int t) { // tへの最短路構築
if (dist[t] >= inf())
return {-1};
vector<int> path;
for (; t != -1; t = prever[t]) {
path.push_back(t);
}
reverse(path.begin(), path.end());
return path;
}
};
int main() {
int n, m;
cin >> n >> m;
UnionFindWeight uf(n);
Graph<int> gr(n);
map<pair<int, int>, int> ma;
rep(i, 0, m) {
int l, r, d;
cin >> l >> r >> d;
l--;
r--;
if (uf.same(l, r)) {
if (uf.dist(l, r) != d) {
if (uf.dist(l, r) < d) {
swap(l, r);
}
gr.dijkstra(l);
auto path = gr.get_path(r);
vector<int> ans;
rep(j, 0, path.size() - 1) {
ans.push_back(ma[{path[j], path[j + 1]}]);
}
ans.push_back(i);
cout << ans.size() << endl;
cout << l + 1 << endl;
rep(j, 0, ans.size()) { cout << ans[j] + 1 << ' '; }
cout << endl;
return 0;
}
} else {
uf.unite(l, r, d);
gr.add_edge(l, r, 1);
gr.add_edge(r, l, 1);
ma[{l, r}] = i;
ma[{r, l}] = i;
}
}
cout << "-1" << endl;
}
SnowBeenDiding