本蒟蒻不会差分约束,就打的 缩点+拓扑 最后三个点wa了实在查不出来
本蒟蒻由于不知道怎样处理几种特殊情况,直接用了两个set和一个map
#include<bits/stdc++.h>
using namespace std;
const int N=1e6+10,K=1e6+10;
int read()
{
int x=0,f=1;
char ch=getchar();
while(ch<'0'||ch>'9')
{
if(f=='-') f=-1;
ch=getchar();
}
while(ch>='0'&&ch<='9')
{
x=x*10+ch-'0';
ch=getchar();
}
return f*x;
}
int n,k;long long ans;
struct query
{
int flag,x,y;
} ask[K];
set< pair<int,int> > mp3,mp5;
map<pair<int,int>,int>mp;
////////////////////////链接表
int edge_cnt,first[N],next[K],to[K],w[K];
void add(int x,int y,int z)
{
next[++edge_cnt]=first[x];
first[x]=edge_cnt;
to[edge_cnt]=y;
w[edge_cnt]=z;
}
///////////////////////并查集
int fa[N],size[N];
int gf(int x)
{
if(fa[x]==x) return fa[x];
fa[x]=gf(fa[x]);
return fa[x];
}
void merge(int x,int y,int i)
{
int u=gf(ask[i].x),v=gf(ask[i].y);
if(u!=v)
{
if(size[u]<size[v]) swap(u,v);
size[u]+=size[v]; size[v]=0;
fa[v]=u;
}
}
//////////////////////拓扑排序
int in[N],candy[N],cnt;
queue<int> q;
void top_sort()
{
for(int i=1;i<=n;++i)
if(size[i]) ++cnt;
for(int i=1;i<=n;++i)
if(in[i]==0&&size[i])
{
q.push(i);
candy[i]=1;
cnt--;
}
while(!q.empty())
{
int x=q.front(); q.pop();
for(int e=first[x];e;e=next[e])
{
--in[to[e]];
if(in[to[e]]==0)
{
candy[to[e]]=candy[x]+mp[make_pair(x,to[e])];
q.push(to[e]);
cnt--;
}
}
}
if(cnt) ans=-1;
else for(int i=1;i<=n;++i)
ans+=candy[gf(i)];
}
/////////////////////主程序
int main()
{
freopen("candy.in","r",stdin);
freopen("candy.out","w",stdout);
n=read();k=read();
for(int i=1;i<=n;++i)
fa[i]=i,size[i]=1;
for(int i=1;i<=k;++i)
ask[i].flag=read(),ask[i].x=read(),ask[i].y=read();//离线
for(int i=1;i<=k;++i)
{
int flag=ask[i].flag,x=ask[i].x,y=ask[i].y;
if(flag==1) merge(x,y,i);
else if(flag==3)
{
if(mp5.count(make_pair(x,y)))
merge(x,y,i);
if(mp3.count(make_pair(y,x)))
merge(x,y,i);
mp3.insert(make_pair(x,y));
}
else if(flag==5)
{
if(mp3.count(make_pair(x,y)))
merge(x,y,i);
if(mp5.count(make_pair(y,x)))
merge(x,y,i);
mp5.insert(make_pair(x,y));
}
}
for(int i=1;i<=k;++i)
{
int flag=ask[i].flag,u=gf(ask[i].x),v=gf(ask[i].y);
if(u==v)
{
if(flag==2||flag==4)
{
printf("-1");
return 0;
}
else continue;
}
if(flag==2)
{
if(mp.count(make_pair(u,v))) mp[make_pair(u,v)]=1;
else add(u,v,1),in[v]++,mp[make_pair(u,v)]=1;
}
else if(flag==3) add(v,u,0),in[u]++,mp[make_pair(v,u)]+=0;
else if(flag==4)
{
if(mp.count(make_pair(v,u))) mp[make_pair(v,u)]=1;
else add(v,u,1),in[u]++,mp[make_pair(v,u)]=1;
}
else add(u,v,0),in[v]++,mp[make_pair(u,v)]+=0;
}
top_sort();
printf("%lld",ans);
}