坑爹数据= =
一道很弱的查分约束,根据题意连边就好惹,然而添加超级源点会RE= =(一直RE看了下discuss发现段神T了一个钟就是因为这个= =),用priorityqueue优化SPFA会无限超时= =
其实感觉用tarjan判环然后在拓扑图上递推能跑的很快的有空试下
#include<iostream>
#include<cstdio>
#include<cmath>
#include<algorithm>
#include<cstring>
#include<cstdlib>
#include<bitset>
#include<queue>
#define LL long long
#define ps(x,y) q.push(hhx(x,y))
#define fo(i,a,b) for(int i=a;i<=b;i++)
#define down(i,a,b) for(int i=a;i>=b;i--)
#define efo(i,x) for(int i=last[x];i!=0;i=e[i].next)
using namespace std;
LL read()
{
LL d=0,f=1;char s=getchar();
while(s<'0'||s>'9'){if(s=='-')f=-1;s=getchar();}
while(s>='0'&&s<='9'){d=d*10+s-'0';s=getchar();}
return d*f;
}
#define N 100005
#define S 100001
#define inf 1000000007
struct hhx
{
int x,dis;
hhx(int a,int b):dis(b),x(a){}
};
struct edge
{
int y,c,next;
}e[N*2];
int last[N],ne=0;
int relax[N],dis[N];
int n,m;
void add(int x,int y,int c)
{
e[++ne].y=y;e[ne].c=c;e[ne].next=last[x];last[x]=ne;
}
queue<hhx>q;
bool spfa()
{
memset(relax,0,sizeof(relax));
bitset<N+5>inq;inq.reset();
inq[S]=1;
fo(i,1,n)
{
dis[i]=1;
ps(i,1);
}
while(!q.empty())
{
hhx now=q.front();
q.pop();
inq[now.x]=0;
efo(i,now.x)
if(dis[now.x]+e[i].c>dis[e[i].y])
{
// cout<<now.x<<' '<<e[i].y<<' '<<dis[now.x]<<' '<<e[i].c<<' '<<dis[e[i].y]<<endl;
dis[e[i].y]=dis[now.x]+e[i].c;
if(++relax[e[i].y]>=n)return 0;
if(inq[e[i].y]==0)
{
ps(e[i].y,dis[e[i].y]);
inq[e[i].y]=1;
}
}
}
return 1;
}
int main()
{
scanf("%d%d",&n,&m);
fo(i,1,m)
{
int k,x,y;scanf("%d%d%d",&k,&x,&y);
if(k==1){add(x,y,0);add(y,x,0);continue;}
if(k==2)
{
if(x==y)
{
puts("-1");
return 0;
}
add(x,y,1);
continue;
}
if(k==3){add(y,x,0);continue;}
if(k==4)
{
if(x==y)
{
puts("-1");
return 0;
}
add(y,x,1);
continue;
}
if(k==5){add(x,y,0);continue;}
}
if(!spfa())puts("-1");
else
{
LL ans=0;
fo(i,1,n)ans+=dis[i];
printf("%lld\n",ans);
}
return 0;
}