QOJ.ac
QOJ
ID | 题目 | 提交者 | 结果 | 用时 | 内存 | 语言 | 文件大小 | 提交时间 | 测评时间 |
---|---|---|---|---|---|---|---|---|---|
#190656 | #2830. Data Structure | qzez# | TL | 0ms | 0kb | C++14 | 4.3kb | 2023-09-29 11:24:58 | 2023-09-29 11:25:00 |
answer
#include<bits/stdc++.h>
using namespace std;
using ll=long long;
template<typename T>
ostream& operator << (ostream &out,const vector<T>&x){
if(x.empty())return out<<"[]";
out<<'['<<x[0];
for(int len=x.size(),i=1;i<len;i++)out<<','<<x[i];
return out<<']';
}
template<typename T>
ostream& operator << (ostream &out,const pair<T,T>&x){
return out<<x.first;
}
template<typename T>
vector<T> ary(const T *a,int l,int r){
return vector<T>{a+l,a+1+r};
}
template<typename T>
void debug(T x){
cerr<<x<<'\n';
}
template<typename T,typename ...S>
void debug(T x,S ...y){
cerr<<x<<' ',debug(y...);
}
const int N=2e5+10;
int n,m,in[N],out[N];
vector<int>ept,ok;
vector<int>only[N];
vector<pair<int,int> >to[N];
void addedge(int u,int v,int i){
out[u]++,in[v]++;
to[u].push_back({v,i});
to[v].push_back({u,-i});
}
#define v e.first
#define w e.second
int vis[N];
bool judge(int u,int fa=0){
vis[u]=1;
if(out[u]==2)return 1;
for(auto e:to[u])if(v^fa){
if(judge(v,u))return 1;
}
return 0;
}
void cover(int u){
if(vis[u])return;
vis[u]=1;
for(auto e:to[u])cover(v);
}
int k,id[N],p[N];
void find(int u,int las=0){
if(vis[u])return;
vis[u]=1,id[++k]=u,p[k]=las;
for(auto e:to[u])find(v,w);
}
vector<pair<int,int> >ans;
void opt(int x,int y){
ans.push_back({abs(x),abs(y)});
}
#define Assert(x) for(int _=x;!_;);
bool solve1(int s){
k=0,find(s);
// for(int i=1;i<=k;i++)debug(id[i],only[id[i]]);
// return 1;
// debug(only[s]);
// Assert(!only[id[1]].empty());
p[1]=only[id[1]].back(),only[id[1]].pop_back();
// Assert(!only[id[k]].empty());
p[k+1]=only[id[k]].back(),only[id[k]].pop_back();
// debug(ary(id,1,k),ary(p,1,k+1));
vector<int>t{1};
for(int i=1;i<=k;i++)if(out[i]==2)t.push_back(i);
for(int len=t.size(),i=1;i<len;i++){
int l=t[i-1],r=t[i],id=-1;
for(int i=l+1;i<r;i++)if(in[i]==2)id=i;
if(ept.empty())return 0;
int x=ept.back();
ept.pop_back();
opt(p[r],x);
if(~id){
for(int i=l;i<id;i++)opt(p[i+1],p[i]);
for(int i=r-1;i>id;i--)opt(p[i],p[i+1]);
int x=p[id],y=p[id+1];
opt(x,y),ept.push_back(x);
}else{
for(int i=r-1;i>=l;i--)opt(p[i],p[i+1]);
ept.push_back(p[l]);
}
p[r]=abs(x);
}
int l=t.back(),r=k+1,id=-1;
for(int i=l+1;i<r;i++)if(in[i]==2)id=i;
if(~id){
for(int i=l;i<id;i++)opt(p[i+1],p[i]);
for(int i=r-1;i>id;i--)opt(p[i],p[i+1]);
int x=p[id],y=p[id+1];
opt(x,y),ept.push_back(x);
}else{
if(p[k]>0){
for(int i=l;i<r;i++)opt(p[i+1],p[i]);
ept.push_back(p[r]);
}else{
for(int i=r;i>l;i--)opt(p[i-1],p[i]);
ept.push_back(p[l]);
}
}
return 1;
}
bool solve2(int s){
// debug("ok1");
int x=-1,y=-1;
for(auto e:to[s])if(w>0)x=v,y=w;
// Assert(find(to[s].begin(),to[s].end(),make_pair(x,y))!=to[s].end());
// Assert(find(to[x].begin(),to[x].end(),make_pair(s,-y))!=to[x].end());
to[s].erase(find(to[s].begin(),to[s].end(),make_pair(x,y)));
to[x].erase(find(to[x].begin(),to[x].end(),make_pair(s,-y)));
out[s]--,in[x]--;
// debug(s,x,to[s],to[x]);
if(ept.empty())return 0;
int z=ept.back();
ept.pop_back();
opt(y,z);
only[s].push_back(z);
only[x].push_back(y);
return solve1(s);
}
#undef v
#undef w
bool get(){
for(int i=1,x,u,v;i<=m;i++){
scanf("%d",&x);
if(!x)ept.push_back(i);
else if(x==1)scanf("%d",&u),only[u].push_back(i);
else if(scanf("%d%d",&u,&v),u!=v)addedge(v,u,i);
else ok.push_back(u);
}
// for(int i=1;i<=n;i++)debug("to",i,to[i]);
fill(vis+1,vis+1+n,0);
for(int x:ok)vis[x]=1;
vector<int>t[3];
for(int i=1;i<=n;i++){
if(!vis[i]&&to[i].size()<=1){
if(judge(i))t[1].push_back(i);
else t[0].push_back(i);
}
}
for(int i=1;i<=n;i++){
if(!vis[i]&&out[i]==2)t[2].push_back(i),cover(i);
}
for(int i=1;i<=n;i++){
if(!vis[i])t[2].push_back(i),cover(i);
}
// debug(ary(t,0,2));
fill(vis+1,vis+1+n,0);
for(int i:t[0]){
if(!solve1(i))return 0;
}
for(int i:t[1]){
if(!solve1(i))return 0;
}
for(int i:t[2]){
if(!solve2(i))return 0;
}
printf("%d\n",(int)ans.size());
for(auto x:ans)printf("%d %d\n",x.first,x.second);
return 1;
}
void clr(){
ept.clear(),ans.clear(),ok.clear();
for(int i=1;i<=n;i++){
only[i].clear(),to[i].clear();
in[i]=out[i]=0;
}
}
int main(){
Assert(0);
for(;~scanf("%d%d",&n,&m);clr())if(!get())puts("-1");
return 0;
}
详细
Test #1:
score: 0
Time Limit Exceeded
input:
2 3 2 1 2 2 1 2 0 1 1 2 1 1 3 4 2 1 3 2 2 3 1 1 1 2