This documentation is automatically generated by online-judge-tools/verification-helper
#include "Graph/bipolar.hpp"
#pragma once #include "DataStructure/linkedlist.hpp" vector<int> BipolarOrientation(int n,vector<vector<int>>& g,int s,int t){ int cur=1; vector<int> par(n),ord(n,-1),low(n),path; auto dfs=[&](auto& dfs,int v)->void{ ord[v]=cur++; low[v]=v; path.push_back(v); for(auto& to:g[v]){ if(ord[to]==-1){ dfs(dfs,to); par[to]=v; if(ord[low[to]]<ord[low[v]]){ low[v]=low[to]; } } else if(ord[to]<ord[low[v]])low[v]=to; } }; ord[s]=0; dfs(dfs,t); if(SZ(path)!=n-1)return {}; path.erase(path.begin()); const bool plus=1,minus=0; vector<int> sign(n); LinkedList<int> LL; vector<LinkedList<int>::Node*> nodes(n); nodes[s]=LL.insert_front(nullptr,s); nodes[t]=LL.insert_back(nodes[s],t); for(auto& v:path){ if(sign[low[v]]==minus){ nodes[v]=LL.insert_front(nodes[par[v]],v); sign[par[v]]=plus; } else{ nodes[v]=LL.insert_back(nodes[par[v]],v); sign[par[v]]=minus; } } auto perm=LL.dump(); // index:vertices vector<int> ret(n); rep(i,0,n)ret[perm[i]]=i; // check vector<int> FROM(n),TO(n); FROM[s]=TO[t]=1; for(auto& v:perm){ if(!FROM[v])return {}; for(auto& to:g[v])if(ret[v]<ret[to]){ FROM[to]=1; } } reverse(ALL(perm)); for(auto& v:perm){ if(!TO[v])return {}; for(auto& to:g[v])if(ret[v]>ret[to]){ TO[to]=1; } } return ret; } /** * @brief Bipolar Orientation */
#line 2 "DataStructure/linkedlist.hpp" template<typename T>struct LinkedList{ struct Node{ T val; Node* head,*tail; Node(){} Node(T v):val(v),head(nullptr),tail(nullptr){} }; Node* front; LinkedList():front(nullptr){} Node* insert_back(Node* v,T x){ if(v==nullptr){ return front=new Node(x); } auto to=v->tail; auto add=new Node(x); v->tail=add; add->head=v; add->tail=to; if(to)to->head=add; return add; } Node* insert_front(Node* v,T x){ if(v==nullptr){ return front=new Node(x); } auto to=v->head; auto add=new Node(x); if(to)to->tail=add; add->head=to; add->tail=v; v->head=add; return add; } vector<T> dump(){ vector<T> ret; Node* cur=front; while(cur){ ret.push_back(cur->val); cur=cur->tail; } return ret; } }; /** * @brief Linked List */ #line 3 "Graph/bipolar.hpp" vector<int> BipolarOrientation(int n,vector<vector<int>>& g,int s,int t){ int cur=1; vector<int> par(n),ord(n,-1),low(n),path; auto dfs=[&](auto& dfs,int v)->void{ ord[v]=cur++; low[v]=v; path.push_back(v); for(auto& to:g[v]){ if(ord[to]==-1){ dfs(dfs,to); par[to]=v; if(ord[low[to]]<ord[low[v]]){ low[v]=low[to]; } } else if(ord[to]<ord[low[v]])low[v]=to; } }; ord[s]=0; dfs(dfs,t); if(SZ(path)!=n-1)return {}; path.erase(path.begin()); const bool plus=1,minus=0; vector<int> sign(n); LinkedList<int> LL; vector<LinkedList<int>::Node*> nodes(n); nodes[s]=LL.insert_front(nullptr,s); nodes[t]=LL.insert_back(nodes[s],t); for(auto& v:path){ if(sign[low[v]]==minus){ nodes[v]=LL.insert_front(nodes[par[v]],v); sign[par[v]]=plus; } else{ nodes[v]=LL.insert_back(nodes[par[v]],v); sign[par[v]]=minus; } } auto perm=LL.dump(); // index:vertices vector<int> ret(n); rep(i,0,n)ret[perm[i]]=i; // check vector<int> FROM(n),TO(n); FROM[s]=TO[t]=1; for(auto& v:perm){ if(!FROM[v])return {}; for(auto& to:g[v])if(ret[v]<ret[to]){ FROM[to]=1; } } reverse(ALL(perm)); for(auto& v:perm){ if(!TO[v])return {}; for(auto& to:g[v])if(ret[v]>ret[to]){ TO[to]=1; } } return ret; } /** * @brief Bipolar Orientation */