QOJ.ac
QOJ
ID | 题目 | 提交者 | 结果 | 用时 | 内存 | 语言 | 文件大小 | 提交时间 | 测评时间 |
---|---|---|---|---|---|---|---|---|---|
#481468 | #7222. The Great Hunt | inksamurai | WA | 0ms | 3708kb | C++23 | 9.0kb | 2024-07-17 06:23:16 | 2024-07-17 06:23:17 |
Judging History
answer
#include <bits/stdc++.h>
// cut here
#ifndef ATCODER_MAXFLOW_HPP
#define ATCODER_MAXFLOW_HPP 1
namespace atcoder {
namespace internal {
template <class T> struct simple_queue {
std::vector<T> payload;
int pos = 0;
void reserve(int n) { payload.reserve(n); }
int size() const { return int(payload.size()) - pos; }
bool empty() const { return pos == int(payload.size()); }
void push(const T& t) { payload.push_back(t); }
T& front() { return payload[pos]; }
void clear() {
payload.clear();
pos = 0;
}
void pop() { pos++; }
};
} // namespace internal
} // namespace atcoder
namespace atcoder {
template <class Cap> struct mf_graph {
public:
mf_graph() : _n(0) {}
explicit mf_graph(int n) : _n(n), g(n) {}
int add_edge(int from, int to, Cap cap) {
assert(0 <= from && from < _n);
assert(0 <= to && to < _n);
assert(0 <= cap);
int m = int(pos.size());
pos.push_back({from, int(g[from].size())});
int from_id = int(g[from].size());
int to_id = int(g[to].size());
if (from == to) to_id++;
g[from].push_back(_edge{to, to_id, cap});
g[to].push_back(_edge{from, from_id, 0});
return m;
}
struct edge {
int from, to;
Cap cap, flow;
};
edge get_edge(int i) {
int m = int(pos.size());
assert(0 <= i && i < m);
auto _e = g[pos[i].first][pos[i].second];
auto _re = g[_e.to][_e.rev];
return edge{pos[i].first, _e.to, _e.cap + _re.cap, _re.cap};
}
std::vector<edge> edges() {
int m = int(pos.size());
std::vector<edge> result;
for (int i = 0; i < m; i++) {
result.push_back(get_edge(i));
}
return result;
}
void change_edge(int i, Cap new_cap, Cap new_flow) {
int m = int(pos.size());
assert(0 <= i && i < m);
assert(0 <= new_flow && new_flow <= new_cap);
auto& _e = g[pos[i].first][pos[i].second];
auto& _re = g[_e.to][_e.rev];
_e.cap = new_cap - new_flow;
_re.cap = new_flow;
}
Cap flow(int s, int t) {
return flow(s, t, std::numeric_limits<Cap>::max());
}
Cap flow(int s, int t, Cap flow_limit) {
assert(0 <= s && s < _n);
assert(0 <= t && t < _n);
assert(s != t);
std::vector<int> level(_n), iter(_n);
internal::simple_queue<int> que;
auto bfs = [&]() {
std::fill(level.begin(), level.end(), -1);
level[s] = 0;
que.clear();
que.push(s);
while (!que.empty()) {
int v = que.front();
que.pop();
for (auto e : g[v]) {
if (e.cap == 0 || level[e.to] >= 0) continue;
level[e.to] = level[v] + 1;
if (e.to == t) return;
que.push(e.to);
}
}
};
auto dfs = [&](auto self, int v, Cap up) {
if (v == s) return up;
Cap res = 0;
int level_v = level[v];
for (int& i = iter[v]; i < int(g[v].size()); i++) {
_edge& e = g[v][i];
if (level_v <= level[e.to] || g[e.to][e.rev].cap == 0) continue;
Cap d =
self(self, e.to, std::min(up - res, g[e.to][e.rev].cap));
if (d <= 0) continue;
g[v][i].cap += d;
g[e.to][e.rev].cap -= d;
res += d;
if (res == up) return res;
}
level[v] = _n;
return res;
};
Cap flow = 0;
while (flow < flow_limit) {
bfs();
if (level[t] == -1) break;
std::fill(iter.begin(), iter.end(), 0);
Cap f = dfs(dfs, t, flow_limit - flow);
if (!f) break;
flow += f;
}
return flow;
}
std::vector<bool> min_cut(int s) {
std::vector<bool> visited(_n);
internal::simple_queue<int> que;
que.push(s);
while (!que.empty()) {
int p = que.front();
que.pop();
visited[p] = true;
for (auto e : g[p]) {
if (e.cap && !visited[e.to]) {
visited[e.to] = true;
que.push(e.to);
}
}
}
return visited;
}
private:
int _n;
struct _edge {
int to, rev;
Cap cap;
};
std::vector<std::pair<int, int>> pos;
std::vector<std::vector<_edge>> g;
};
} // namespace atcoder
#endif // ATCODER_MAXFLOW_HPP
// cut here
using namespace std;
#define rep(i,n) for(int i=0;i<n;i++)
#define per(i,n) for(int i=n-1;i>=0;i--)
#define rng(i,c,n) for(int i=c;i<n;i++)
#define fi first
#define se second
#define pb push_back
#define sz(a) (int) a.size()
#define all(a) a.begin(),a.end()
#define vec(...) vector<__VA_ARGS__>
#define _3zlqvu8 ios::sync_with_stdio(0),cin.tie(0)
typedef long long ll;
typedef vector<int> vi;
typedef pair<int,int> pii;
void print(){cout<<'\n';}
template<class h,class...t>
void print(const h&v,const t&...u){cout<<v<<' ',print(u...);}
#define nare cout<<"No\n"; exit(0);
#define yare cout<<"Yes\n";
struct treelca{
int n;
vi seg;
vec(vi) adj;
int timer;
vi tin,tout,tour,tourid,depth;
treelca(int m,int root,vec(vi) neadj){
init(m,root,neadj);
}
void init(int m,int root,vec(vi) neadj){
n=m;
timer=0;
tin=tout=tourid=depth=vi(n,0);
adj=neadj;
dfs(root,-1);
seg.resize(4*sz(tour));
build(1,0,sz(tour)-1);
}
void dfs(int v,int par){
tour.pb(v);
tourid[v]=sz(tour)-1;
tin[v]=timer++;
for(auto u:adj[v]){
if(u==par) continue;
depth[u]=depth[v]+1;
dfs(u,v);
tour.pb(v);
}
tout[v]=timer++;
}
void build(int node,int l,int r){
if(l==r){
seg[node]=tour[l];
}else{
int m=(l+r)>>1;
build(node*2,l,m);
build(node*2+1,m+1,r);
seg[node]=(tin[seg[node*2]]<tin[seg[node*2+1]]?
seg[node*2]:
seg[node*2+1]);
}
}
int query(int node,int l,int r,int _l,int _r){
if(l>_r or r<_l) return -1;
if(l>=_l and r<=_r) return seg[node];
int m=(l+r)>>1;
int vl=query(node*2,l,m,_l,_r),vr=query(node*2+1,m+1,r,_l,_r);
if(min(vl,vr)==-1) return max(vl,vr);
return (tin[vl]<tin[vr]?vl:vr);
}
int ancestor(int from,int to){
int tinfrom=tin[from],tinto=tin[to];
if(tinfrom>tinto) swap(tinfrom,tinto);
return query(1,0,sz(tour)-1,tinfrom,tinto);
}
int dist(int u,int v){
return depth[u]+depth[v]-depth[ancestor(u,v)]*2;
}
};
void slv(){
int n;
cin>>n;
vec(vi) adj(n);
rep(i,n-1){
int u,v;
cin>>u>>v;
u-=1,v-=1;
adj[u].pb(v),adj[v].pb(u);
}
vec(pii) a;
rep(i,n){
int s,e;
cin>>s>>e;
s-=1,e-=1;
a.pb({s,e});
}
vec(pii) to(n,{-1,-1});
vec(vec(pii)) adqry(n);
treelca lca(n,0,adj);
rep(i,n){
auto [s,e]=a[i];
int ho=0;
if(s>0 and e>0){
int up=lca.ancestor(s,e);
if(up==s or up==e){
if(lca.depth[s]>lca.depth[e]){
swap(s,e);
}
adqry[e].pb({lca.depth[s],i});
}else{
ho=1;
}
}else{
ho=1;
}
if(ho){
to[i]={s,e};
}
}
vi pns(n,-1);
vi par(n);
multiset<pii> mst;
auto dfs=[&](auto self,int v)->void{
int taken=0;
for(auto u:adj[v]){
if(u==par[v]) continue;
par[u]=v;
self(self,u);
if(v==0){
if(sz(mst)){
if(sz(mst)>1){
nare;
}
if(!taken){
pns[(*mst.begin()).se]=v;
taken=1;
mst.clear();
}else{
nare;
}
}
}
}
for(auto [d,x]:adqry[v]){
mst.insert({d,x});
}
if(v==0 and taken and sz(mst)){
nare;
}
if(sz(mst)){
auto it=prev(mst.end());
pii p=*it;
if(p.fi>lca.depth[v]){
nare;
}
pns[p.se]=v;
mst.erase(it);
}
};
dfs(dfs,0);
vi usd(n);
rep(v,n){
if(pns[v]!=-1){
usd[pns[v]]=1;
}
}
int si=0;
rep(v,n){
if(to[v].fi!=-1){
si+=1;
}
}
const int src=2*n;
const int sink=2*n+1;
atcoder::mf_graph<int> g(2*n+2);
rep(v,n){
auto [s,e]=to[v];
if(s!=-1){
g.add_edge(src,v,1);
g.add_edge(v,s+n,1);
g.add_edge(v,e+n,1);
}
}
rep(v,n){
if(!usd[v]){
g.add_edge(v+n,sink,1);
}
if(v){
g.add_edge(v+n,par[v]+n,1e9);
}
}
int cur=g.flow(src,sink);
if(cur!=si){
nare;
}
vec(vi) adqry1(n);
for(auto e:g.edges()){
if(e.flow==0) continue;
if(e.from<n){
int to=e.to-n;
adqry1[to].pb(e.from);
}
}
set<int> st;
auto rfs=[&](auto self,int v)->void{
for(auto u:adj[v]){
if(u==par[v]) continue;
self(self,u);
}
for(auto x:adqry1[v]){
st.insert(x);
}
if(sz(st)){
auto it=st.begin();
pns[*it]=v;
st.erase(it);
}
};
rfs(rfs,0);
rep(v,n){
cout<<pns[v]+1<<" ";
}
cout<<"\n";
}
signed main(){
_3zlqvu8;
slv();
}
详细
Test #1:
score: 0
Wrong Answer
time: 0ms
memory: 3708kb
input:
10 2 1 3 1 6 1 8 2 4 3 9 6 5 4 7 8 10 7 8 7 10 2 7 2 10 1 3 1 5 2 5 1 6 1 9 2 3 4
output:
7 10 8 1 3 2 5 6 9 4
result:
wrong answer