P3561。用洛谷 IDE 在这个样例 RE(C++14 O2),但是 C++14 没问题。
4
1
1 1
1 0 1
#include<bits/stdc++.h>
using namespace std;
const int N = 1e5 + 10;
int a[2010][2010];
int dfn[N], low[N], cur, stk[N], instk[N], top, bel[N], cnt, w[N], d[N];
vector<int>g[N],s[N];
int pop(){instk[stk[top]] = 0;return stk[top--];}
void tarjan(int x)
{
dfn[x] = low[x] = ++cur, stk[++top] = x, instk[x] = 1;
for(auto j:g[x]) if(!dfn[j]) tarjan(j), low[x] = min(low[x],low[j]);
else if(instk[j]) low[x] = min(low[x],dfn[j]);
if(dfn[x]==low[x])
{
d[++cnt] = x;
while(stk[top]!=x) s[cnt].emplace_back(stk[top]), bel[pop()] = cnt;
s[cnt].emplace_back(stk[top]), bel[pop()] = cnt;
}
}
int ed(int x, int y){if(x>y)return a[y][x] == 0;else return a[x][y] == 1;}
vector<int>c,v,r;//chain,ring
int vis[N], pos[N];
int mmain(vector<int> &s)
{
c.clear(), r.clear();
c.emplace_back(s[0]);
memset(vis,0,sizeof vis);
int i, j;
for(i=1;i<s.size();i++)
{
int x = s[i];
for(j=0;j<c.size();j++) if(ed(x,c[j])) break;
int p = j;
v.clear();
for(j=0;j<p;j++) v.emplace_back(c[j]);
v.emplace_back(x);
for(j=p;j<c.size();j++) v.emplace_back(c[j]);
c.clear();
for(auto j:v) c.emplace_back(j);
}
for(i=0;i<c.size()-1;i++) assert(ed(c[i],c[i+1]));
r.emplace_back(c[0]), vis[c[0]] = 1;
int lst = 0;
for(i=1;i<c.size();i++)
{
int x = 0;
for(j=0;j<r.size();j++) pos[r[j]] = j;
for(auto j:g[c[i]]) if(vis[j]) {if(!x||pos[j]<pos[x]) x = j;}
if(!x) continue;
for(j=0;j<r.size();j++) if(r[j]==x) break;
int p = j;
v.clear();
for(j=p;j<=lst;j++) v.emplace_back(r[j]);
for(j=0;j<p;j++) v.emplace_back(r[j]);
for(j=lst+1;j<=i;j++) v.emplace_back(c[j]);
lst = i;
r.clear();
for(auto j:v) r.emplace_back(j);
for(auto i:r) vis[i] = 1;
assert(lst==r.size()-1);
}
for(i=0;i<r.size()-1;i++) assert(ed(r[i],r[i+1]));
if(r.size()>1) assert(ed(r[r.size()-1],r[0]));
s.clear();for(auto j:r) s.emplace_back(j);
}
int main()
{
int n, i, j;
scanf("%d", &n);
for(i=2;i<=n;i++) for(j=1;j<i;j++) scanf("%d", &a[j][i]),
g[j*a[j][i]+i*(1-a[j][i])].emplace_back(j*(1-a[j][i])+i*a[j][i]);
for(i=1;i<=n;i++) if(!dfn[i]) tarjan(i);
for(i=1;i<=cnt;i++) w[i] = s[i].size() + w[i-1];
for(i=1;i<=cnt;i++) mmain(s[i]);
for(i=1;i<=n;i++)
{
printf("%d", w[bel[i]]);
int a = i, cnt = 0;
for(;;)
{
int pos, sz = s[bel[a]].size();
for(pos=0;pos<sz;pos++) if(s[bel[a]][pos]==a) break;
printf(" %d", s[bel[a]][pos]), cnt++;
for(j=(pos+1)%sz;j!=pos;j=(j+1)%sz) printf(" %d", s[bel[a]][j]), cnt++;
if(bel[a]==1) break;
a = d[bel[a]-1];
}
printf("\n");
}
return 0;
}