题解:CF2245D2 Construct an Array (Hard Version)
preface
这个构造太神了,一下子没有想到。
solution
我们注意到
然后我们注意无解当且仅当有两点强连通。如果有解即是若干的个有向无环图,考虑求出每点的拓扑序
然后非常神的一个构造是另
code
#include<bits/stdc++.h>
using namespace std;
const int N=1000000;
int T,n,m,pos[N],cnt,in[N];
vector<int> v[N];
queue<int> q;
void solve()
{
cin>>n>>m;
cnt=0;
for(int i=1;i<=2*n;i++)
{
v[i].clear();
pos[i]=in[i]=0;
}
for(int i=1;i<=m;i++)
{
int op,x,y;
cin>>op>>x>>y;
if(op==1)
{
v[x+n].push_back(y);
v[y+n].push_back(x);
in[y]++,in[x]++;
}
else
{
v[x].push_back(y+n);
v[y].push_back(x+n);
in[x+n]++,in[y+n]++;
}
}
for(int i=1;i<=2*n;i++)
{
if(!in[i])
{
q.push(i);
}
}
while(!q.empty())
{
int x=q.front();
q.pop();
cnt++;
pos[x]=cnt;
for(auto i:v[x])
{
in[i]--;
if(!in[i])
{
q.push(i);
}
}
}
if(cnt<2*n)
{
cout<<"NO\n";
return;
}
cout<<"YES\n";
for(int i=1;i<=n;i++)
{
cout<<pos[i]-pos[i+n]<<" ";
}
cout<<"\n";
return;
}
int main()
{
ios::sync_with_stdio(false);
cin.tie(0);
cin>>T;
while(T--)
{
solve();
}
return 0;
}