差分约束接着水
不过这题还需要一个在每一个小朋友至少一颗糖的情况下的最小值
直接遍历一下每一个点的最短路即可
#include<iostream>
#include<cstdio>
using namespace std;
int n,k,cnt,q[100003],head[100003],cir[100003],dis[100003];
long long ans;
bool inq[100003];
struct data{
int to,next,v;
}e[400003];
inline void insert(int u,int v,int w){
e[++cnt].to=v;
e[cnt].next=head[u];
e[cnt].v=w;
head[u]=cnt;
}
bool spfa(){
int t=0,w=1,now;
q[0]=0;inq[0]=1;cir[0]=1;
while(t!=w){
now=q[t++];
t%=100000;
for(int i=head[now];i;i=e[i].next){
if(dis[now]+e[i].v>dis[e[i].to]){
dis[e[i].to]=dis[now]+e[i].v;
if(++cir[e[i].to]>=n){
return 0;
}
if(!inq[e[i].to]){
inq[e[i].to]=1;
q[w++]=e[i].to;
w%=100000;
}
}
}
inq[now]=0;
}
return 1;
}
int main(){
cin>>n>>k;
int x,a,b;
while(k--){
cin>>x>>a>>b;
if(x==1){
insert(a,b,0);
insert(b,a,0);
}else if(x==2){
if(a==b){
printf("-1");
return 0;
}
insert(a,b,1);
}else if(x==3){
insert(b,a,0);
}else if(x==4){
if(a==b){
printf("-1");
return 0;
}
insert(b,a,1);
}else{
insert(a,b,0);
}
}
for(int i=n;i>0;i--){
insert(0,i,1);
}
if(!spfa()){
cout<<-1<<endl;
return 0;
}
for(int i=1;i<=n;i++){
ans+=dis[i];
}
cout<<ans<<endl;
return 0;
}
/*
in:
5 7
1 1 2
2 3 2
4 4 1
3 4 5
5 4 5
2 3 5
4 5 1
out:
11
*/