結果
| 問題 |
No.3104 Simple Graph Problem
|
| コンテスト | |
| ユーザー |
pockyny
|
| 提出日時 | 2025-04-20 19:34:50 |
| 言語 | C++17 (gcc 13.3.0 + boost 1.87.0) |
| 結果 |
TLE
|
| 実行時間 | - |
| コード長 | 4,707 bytes |
| コンパイル時間 | 1,633 ms |
| コンパイル使用メモリ | 99,140 KB |
| 実行使用メモリ | 36,980 KB |
| 最終ジャッジ日時 | 2025-04-20 19:34:56 |
| 合計ジャッジ時間 | 6,051 ms |
|
ジャッジサーバーID (参考情報) |
judge1 / judge4 |
(要ログイン)
| ファイルパターン | 結果 |
|---|---|
| sample | AC * 3 |
| other | AC * 5 TLE * 1 -- * 59 |
ソースコード
#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);
}
}
cerr << "DEBUG\n";
for(int x:ver) cerr << x << " ";
cerr << "\n";
for(int id:ed) cerr << id << " ";
cerr << "\n";
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]];
}
}
cerr << "val == " << val.val() << "\n";
add_op(x,y,e,val/2);
for(int u:ver) cerr << (b[u] - a[u]).val() << " ";
cerr << "\n";
// x -> yのパスに沿って塗る
// solve_dfsとは違う順番じゃないとダメ (verの順になる)
while(ver.size()){
int z = ver.back();
ver.pop_back();
if(ver.size()){
mint c = b[z] - a[z];
cerr << "val == " << c.val() << "\n";
cerr << "z == " << z << " " << ver.back() << "\n";
add_op(z,ver.back(),ed.back(),c);
for(int id=0;id<n;id++){
cerr << a[id].val() << " " << deb_a[id].val() << "\n";
}
}
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";
}
}
pockyny