結果
問題 | No.3104 Simple Graph Problem |
ユーザー |
![]() |
提出日時 | 2025-04-20 19:36:10 |
言語 | C++17 (gcc 13.3.0 + boost 1.87.0) |
結果 |
AC
|
実行時間 | 369 ms / 2,000 ms |
コード長 | 4,117 bytes |
コンパイル時間 | 1,528 ms |
コンパイル使用メモリ | 98,036 KB |
実行使用メモリ | 28,884 KB |
最終ジャッジ日時 | 2025-04-20 19:36:26 |
合計ジャッジ時間 | 16,014 ms |
ジャッジサーバーID (参考情報) |
judge4 / judge3 |
(要ログイン)
ファイルパターン | 結果 |
---|---|
sample | AC * 3 |
other | AC * 65 |
ソースコード
#include <iostream> #include <atcoder/modint> #include <vector> #include <cassert> using namespace std; using namespace atcoder; using mint = modint998244353; vector<pair<int,int>> G[100010]; int c[100010],comp[100010],par[100010],par_id[100010],d[100010]; void dfs(int s,int p,int col,int x){ c[s] = col; comp[s] = x; par[s] = p; for(auto [v,id]:G[s]){ if(c[v]!=-1) continue; par[v] = v; par_id[v] = id; d[v] = d[s] + 1; dfs(v,s,1 - col,x); } } mint deb_a[100010]; int u[100010],v[100010]; mint a[100010],b[100010],ans[100010]; void add_op(int x,int y,int id,mint c){ assert((x==v[id] && y==u[id]) || (x==u[id] || y==v[id])); a[x] += c; a[y] += c; deb_a[u[id]] += c; deb_a[v[id]] += c; ans[id] += c; } bool vis[100010]; void solve_dfs(int s,int p,int id){ if(vis[s]) return; vis[s] = true; for(auto [v,id]:G[s]){ if(vis[v]) continue; solve_dfs(v,s,id); } if(p!=-1 && id!=-1){ mint c = b[s] - a[s]; add_op(s,p,id,c); } } #include <cassert> #include <algorithm> // (頂点,辺) pair<vector<int>,vector<int>> get_path(int from,int to){ assert(from!=to); int a = from,b = to; vector<int> v1,v2,e1,e2; v1.push_back(a); v2.push_back(b); while(a!=b){ if(d[a]>d[b]){ v1.push_back(par[a]); e1.push_back(par_id[a]); a = par[a]; }else{ v2.push_back(par[b]); e2.push_back(par_id[b]); b = par[b]; } } reverse(v2.begin(),v2.end()); reverse(e2.begin(),e2.end()); // lcaが被る v1.pop_back(); v1.insert(v1.end(),v2.begin(),v2.end()); e1.insert(e1.end(),e2.begin(),e2.end()); return {v1,e1}; } #include <set> int main(){ ios_base::sync_with_stdio(false); cin.tie(NULL); int i,n,m; cin >> n >> m; for(i=0;i<n;i++){ int x; cin >> x; b[i] = x; } for(i=0;i<m;i++){ cin >> u[i] >> v[i]; u[i]--; v[i]--; G[u[i]].push_back({v[i],i}); G[v[i]].push_back({u[i],i}); } for(i=0;i<n;i++) c[i] = -1; for(i=0;i<n;i++){ if(c[i]==-1) dfs(i,-1,0,i); } vector<vector<int>> cc(n); for(i=0;i<n;i++){ cc[comp[i]].push_back(i); } bool f = true; for(i=0;i<n;i++){ bool is_bip = true; int x = -1,y = -1,e = -1; for(int v:cc[i]){ for(auto [u,id]:G[v]){ if(c[v]==c[u]){ is_bip = false; x = v; y = u; e = id; } } } if(is_bip){ solve_dfs(i,-1,-1); }else{ auto [ver,ed] = get_path(x,y); set<int> s; for(int v:ver) s.insert(v); for(int v:ver){ for(auto [u,id]:G[v]){ if(s.count(u)) continue; s.insert(u); solve_dfs(u,v,id); } } mint val = b[x] - a[x] + b[y] - a[y]; for(int id=1;id<(int)ver.size() - 1;id++){ if(id&1){ val -= b[ver[id]] - a[ver[id]]; }else{ val += b[ver[id]] - a[ver[id]]; } } add_op(x,y,e,val/2); // x -> yのパスに沿って塗る // solve_dfsとは違う順番じゃないとダメ (verの順になる) while(ver.size()){ int z = ver.back(); ver.pop_back(); if(ver.size()){ mint c = b[z] - a[z]; add_op(z,ver.back(),ed.back(),c); } ed.pop_back(); } } } bool ok = true; for(i=0;i<n;i++){ if(a[i]!=b[i]) ok = false; } if(ok){ for(i=0;i<m;i++) cout << ans[i].val() << " "; cout << "\n"; for(i=0;i<n;i++) cerr << deb_a[i].val() << " "; cerr << "\n"; }else{ cout << -1 << "\n"; for(i=0;i<n;i++) cerr << a[i].val() << " "; cerr << "\n"; } }