无tarjan,无SPFA,无差分约束,无0-1bfs,纯拓扑排序
加强版和原版都过了
#include<bits/stdc++.h>
using namespace std;
#define int long long
#define N 100010
struct node{
int v,w;
};
vector<node> g[N];
int du[N],d[N],n;
signed q[200010];
bool vis[N],vs[N];
bool topo(){
int l=1,r=0;
for(int i=1;i<=n;i++){
if(du[i]==0){
q[++r]=i;
vis[i]=1;
}
}
if(!r) return 0;
int u,v,w,x,cnt=0;
while(l<=r){
cnt++;
u=q[l];
d[u]=max(d[u],1ll);
vs[u]=0;
for(int i=0;i<g[u].size();++i){
v=g[u][i].v;
x=d[v];
if(g[u][i].w==1) d[v]=max(d[v],d[u]);
else if(g[u][i].w==2){
d[v]=max(d[v],d[u]+1);
du[v]--;
}
if(du[v]==0 && !vis[v] && !vs[v]){
if(g[q[l+1]].size()>=g[v].size()){
l--;
q[l+1]=v;
}
else q[++r]=v;
vis[v]=1;
vs[v]=1;
}
else if(vis[v] && x!=d[v] && !vs[v]){
if(g[q[l+1]].size()>=g[v].size() && l>=1){
l--;
q[l+1]=v;
}
else q[++r]=v;
vs[v]=1;
}
}
l++;
if(cnt>=n*2) return 0;
}
for(int i=1;i<=n;i++)
if(!vis[i]) return 0;
return 1;
}
signed main(){
ios::sync_with_stdio(0),cin.tie(0),cout.tie(0);
int k,ans=0;
cin>>n>>k;
for(int i=1;i<=k;i++){
int op,x,y;
cin>>op>>x>>y;
if(op==1){
g[x].push_back({y,1});
g[y].push_back({x,1});
}
if(op==2){
g[x].push_back({y,2});
du[y]++;
}
if(op==3) g[y].push_back({x,1});
if(op==4){
g[y].push_back({x,2});
du[x]++;
}
if(op==5) g[x].push_back({y,1});
if((op==2 || op==4) && x==y){
cout<<-1<<endl;
return 0;
}
}
if(!topo()){
puts("-1");
return 0;
}
for(int i=1;i<=n;i++) ans+=d[i];
cout<<ans;
return 0;
}