差分约束裸题,对于给出的信息进行建图。
对于查分约束可以看这里:https://blog.csdn.net/zzk_233/article/details/83789271
#include<cstdio>
#include<algorithm>
#include<cmath>
#include<cstring>
#include<queue>
using namespace std;
typedef long long ll;
struct node
{
int to,nxt,val;
}edge[400005];
int head[100005],cnt=1;
int n,k;
void init()
{
memset(head,-1,sizeof(head));
}
void add(int from,int to,int val)
{
edge[cnt].to=to;
edge[cnt].val=val;
edge[cnt].nxt=head[from];
head[from]=cnt++;
}
int dis[100005],used[100005],in[100005];
queue<int>M;
void spfa()
{
memset(dis,-0x3f,sizeof(dis));
dis[0]=0;
used[0]=1;
M.push(0);
while(!M.empty())
{
int u=M.front();M.pop();
if(in[u]>n)
{
printf("-1");
exit(0);
}
for(int i=head[u];i!=-1;i=edge[i].nxt)
{
int to=edge[i].to;
if(dis[to]<dis[u]+edge[i].val)
{
dis[to]=dis[u]+edge[i].val;
if(used[to])continue;
M.push(to);used[to]=1;in[u]++;
}
}
used[u]=0;
}
}
int main()
{
init();
scanf("%d%d",&n,&k);
for(int i=1;i<=k;i++)
{
int a,b,c;
scanf("%d%d%d",&c,&a,&b);
if(c==1)add(a,b,0),add(b,a,0);
if(c==2)
{
add(a,b,1);
if(a==b)
{
printf("-1");
return 0;
}
}
if(c==3)add(b,a,0);
if(c==4)
{
add(b,a,1);
if(a==b)
{
printf("-1");
return 0;
}
}
if(c==5)add(a,b,0);
}
for(int i=n;i>=1;i--)
{
add(0,i,1);
}
spfa();
ll ans=0;
for(int i=n;i>=1;i--)
{
ans+=(ll)dis[i];
}
printf("%lld",ans);
return 0;
}