裸的差分约束系统.建图很好建,跑一个最长路就可以了
#include<iostream>
#include<cstdio>
#include<cstring>
#include<string>
#include<algorithm>
#include<queue>
using namespace std;
const int N=100010;
struct edge{
int v,w,next;
}e[300010];
long long ans;
int te,k,n;
int head[N],d[N],inq[N],vis[N];
queue<int>q;
inline int F()
{
register int aa,bb;register char ch;
while(ch=getchar(),(ch<'0'||ch>'9')&&ch!='-');ch=='-'?aa=bb=0:(aa=ch-'0',bb=1);
while(ch=getchar(),ch>='0'&&ch<='9')aa=(aa<<3)+(aa<<1)+ch-'0';return bb?aa:-aa;
}
void add(int u,int v,int w)
{
e[++te].v=v;
e[te].w=w;
e[te].next=head[u];
head[u]=te;
}
int spfa(int s)
{
memset(inq,0,sizeof(inq));
memset(vis,0,sizeof(vis));
memset(d,128,sizeof(d));
while(!q.empty())q.pop();
inq[s]=1;vis[s]=1;q.push(s);d[s]=0;
while(!q.empty())
{
int u=q.front();q.pop();vis[u]=0;
for (int i=head[u];i;i=e[i].next)
{
int v=e[i].v;
if (d[v]<d[u]+e[i].w)
{
d[v]=e[i].w+d[u];
if (!vis[v])
{
q.push(v);
vis[v]=1;
inq[v]++;
if (inq[v]>n)return 0;
}
}
}
}
return 1;
}
int main()
{
te=0;
memset(head,0,sizeof(head));
int op,u,v;
scanf("%d%d",&n,&k);
for (int i=1;i<=k;i++)
{
scanf("%d%d%d",&op,&u,&v);
if (op==1)
add(u,v,0),add(v,u,0);
else if (op==2)
add(u,v,1);
else if (op==3)
add(v,u,0);
else if (op==4)
add(v,u,1);
else add(u,v,0);
if ((op==2||op==4)&&u==v){cout<<-1<<endl;return 0;}
}
for (int i=n;i>=1;--i)
add(0,i,1);
if (!spfa(0))
cout<<-1;
else
{
for (int i=1;i<=n;++i)
ans+=d[i];
cout<<ans;
}
}