P8066 Fan Groups
考虑先去除图上边权为 \(1\) 的边然后跑一个 tarjan 缩强联通分量。
现在图上有若干个 DAG,每一个 DAG 只能有一个度数为 \(0\) 的强联通分量,不然显然无解。
然后这一个 DAG 的构造方案就是找到度数为 \(0\) 的强联通分量,然后输出其中一个点,剩下的随便你排布。
现在考虑边权为 \(1\) 的边带来的影响。
我们设 \(d_i\) 表示 \(i\) 所在的 DAG 编号,那么一条边 \((x,y,1)\) 限制的实际上就是 \(d_y\) 要在 \(d_x\) 之前。
建出图然后拓扑排序即可。时间复杂度 \(O(n+m)\)。为啥有紫呢?
//code by Emissary
#include<bits/stdc++.h>
#define pb push_back
using namespace std;
const int MAXN = 2e5+5;
int n, m;
int hd, tl, Q[MAXN], fa[MAXN];
int stk[MAXN], bel[MAXN], topf, tot;
int low[MAXN], dfn[MAXN], du[MAXN], colcnt;
int head[MAXN], ne[MAXN<<1], to[MAXN<<1], bl[MAXN], cnt;
bool ins[MAXN], vis[MAXN];
vector<int> node[MAXN], f[MAXN];
inline int find(int x){return x==fa[x]?x:fa[x]=find(fa[x]);}
inline void add(int x, int y){++cnt;to[cnt]=y;ne[cnt]=head[x];head[x]=cnt;}
inline void tarjan(int x){
low[x]=dfn[x]=++tot; ins[x]=1; stk[++topf]=x;
for(int i=head[x];i;i=ne[i]){
if(dfn[to[i]]){
if(ins[to[i]]) low[x]=min(low[x],dfn[to[i]]);
}
else tarjan(to[i]), low[x]=min(low[x],low[to[i]]);
}
if(dfn[x]==low[x]){
stk[topf+1]=0; ++colcnt;
while(stk[topf+1]!=x){
int t=stk[topf]; bel[t]=bl[t]=colcnt;
ins[stk[topf]]=0; node[colcnt].pb(t);
--topf;
}
}
return ;
}
inline void dfs(int x, int b){
bel[x]=b; f[b].pb(x);
for(auto i:node[x]) vis[i]=1;
for(auto i:node[x]){
for(int j=head[i];j;j=ne[j]){
if(vis[to[j]]) continue;
dfs(bl[to[j]],b);
}
}
return ;
}
signed main(){
ios::sync_with_stdio(0);
vector<pair<int,int> > E; cin >> n >> m;
for(int i=1;i<=n;++i) fa[i]=i;
for(int i=1;i<=m;++i){
int x, y, c;
cin >> x >> y >> c;
if(c==0) add(x,y), fa[find(x)]=find(y);
else E.pb(make_pair(x,y));
}
int tot=0, all=0;
for(int i=1;i<=n;++i) tot+=find(i)==i;
for(int i=1;i<=n;++i) if(!dfn[i]) tarjan(i);
for(int i=1;i<=n;++i) for(int j=head[i];j;j=ne[j]) if(bel[i]!=bel[to[j]]) du[bel[to[j]]]++;
for(int i=1;i<=colcnt;++i) all+=du[i]==0;
if(tot!=all) return cout << -1, 0; hd=1, tl=0;
for(auto &i:E) i.first=bel[i.first], i.second=bel[i.second];
for(int i=1;i<=colcnt;++i) if(du[i]==0) dfs(i,all), all--;
memset(du,0,sizeof du); memset(head,0,sizeof head); cnt=0;
for(auto i:E) add(bel[i.second],bel[i.first]), du[bel[i.first]]++;
for(int i=1;i<=tot;++i) if(du[i]==0) Q[++tl]=i; int t; vector<int> ans;
while(hd<=tl){
t=Q[hd++];
for(auto i:f[t]) for(auto j:node[i]) ans.pb(j);
for(int i=head[t];i;i=ne[i]) if((--du[to[i]])==0) Q[++tl]=to[i];
}
if(tl!=tot) cout << -1;
else for(auto i:ans) cout << i << ' ';
return 0;
}

浙公网安备 33010602011771号