[CF1804E] Routing 题解
aeiouaoeiu · · 题解
@Departure_ 这么强!!!!!
拿样例来研究一下,容易发现这个
首先每棵树的环外点深度可以控制在
于是我们得到了一个很简洁的性质:
然后怎么找环呢?可以考虑先找到一个链,一个朴素的想法是设
时间复杂度
::::info[code]
#include<bits/stdc++.h>
#define pb emplace_back
#define mp make_pair
#define pob pop_back
using namespace std;
typedef long long ll;
const ll N=20,p=1e9+7,ee=1e18;
ll n,m,G[N+5],f[1<<N],ans[N+5];
ll _(ll x){return (1<<(x-1));}
void check(ll S){
ll u=0,cur,T;
for(ll i=1;i<=n;i++)if(S>>(i-1)&1){u=i; break;}
cur=G[u]&f[S];
if(!cur) return;
for(ll i=1;i<=n;i++) ans[i]=0;
T=S;
for(ll v,lst=u;;){
if(!cur) return;
v=__lg(cur&(-cur))+1,ans[v]=lst,S^=_(v);
if(S==_(u)){ans[u]=v; break;}
cur=(f[S]&G[v]),lst=v;
}
cout<<"Yes\n";
for(ll i=1;i<=n;i++)if(T>>(i-1)&1){
for(ll j=1;j<=n;j++){
if(ans[j]) continue;
if(G[i]>>(j-1)&1) ans[j]=i;
}
}
for(ll i=1;i<=n;i++) cout<<ans[i]<<" "; cout<<"\n";
exit(0);
}
int main(void){
//freopen("data.in","r",stdin);
//freopen("data.out","w",stdout);
ios::sync_with_stdio(0),cin.tie(0);
cin>>n>>m;
for(ll i=1,u,v;i<=m;i++){
cin>>u>>v;
G[u]|=_(v),G[v]|=_(u);
if(u>v) swap(u,v);
f[_(u)|_(v)]=_(v);
}
for(ll i=1;i<=n;i++) G[i]|=_(i);
for(ll S=0,val;S<(1<<n);S++)if(f[S]){
val=0;
for(ll i=1;i<=n;i++){
if(S>>(i-1)&1){
val|=G[i];
continue;
}
if(__lg(S&(-S))+1>=i) continue;
if(f[S]&G[i]) f[S|_(i)]|=_(i);
}
if(val==(1<<n)-1) check(S);
}
cout<<"No\n";
return 0;
}
::::