很久以前学的差分约束,基本忘了,复习一下
a<=b+c,ins(b,a,c)是最短链,每个元素最大
a>=b+c,ins(b,a,c)是最长链,每个元素最小
#include<bits/stdc++.h>
#pragma comment(linker, "/STACK:1024000000,1024000000")
#include<stdio.h>
#include<algorithm>
#include<queue>
#include<string.h>
#include<iostream>
#include<math.h>
#include<set>
#include<map>
#include<vector>
#include<iomanip>
using namespace std;
#define ll long long
#define pb push_back
#define FOR(a) for(int i=1;i<=a;i++)
const int inf=0x3f3f3f3f;
const int maxn=1e5+5;
int n,m,s;
struct EDGE{int v,ne;double w;}e[maxn<<1];
int h[maxn],cnt=0;
inline void ins(int u,int v,int w){
cnt++;
e[cnt].v=v;e[cnt].w=w;e[cnt].ne=h[u];h[u]=cnt;
}
int q[maxn],head,tail,inq[maxn],num[maxn],d[maxn];
inline void lop(int &x){if(x==maxn)x=1;}
bool spfa(int s){
for(int i=1;i<=n;i++)d[i]=-inf;
head=tail=0;
memset(inq,0,sizeof inq);
memset(num,0,sizeof num);
for(int i=1;i<=n;i++)q[tail++]=i,inq[i]=1,d[i]=1;
while(head!=tail){
int u=q[head++];inq[u]=0;lop(head);
for(int i=h[u];i;i=e[i].ne){
int v=e[i].v,w=e[i].w;
if(d[v]<d[u]+w){
d[v]=d[u]+w;
if(!inq[v]){
inq[v]=1,q[tail++]=v,lop(tail);
if(++num[v]>n)return 1;
}
}
}
}
return 0;
}
int main(){
scanf("%d%d",&n,&m);
s=0;
for(int i=1,x,a,b;i<=m;i++){
scanf("%d%d%d",&x,&a,&b);
if(x==1)ins(a,b,0),ins(b,a,0);
else if(x==2){if(a==b){puts("-1");return 0;}ins(a,b,1);}
else if(x==3){ins(b,a,0);}
else if(x==4){if(a==b){puts("-1");return 0;}ins(b,a,1);}
else ins(a,b,0);
}
if(spfa(s))puts("-1");
else{
ll ans=0;
for(int i=1;i<=n;i++)ans+=d[i];
printf("%lld\n",ans);
}
}