连差分约束不知道是什么的:http://www.cnblogs.com/void/archive/2011/08/26/2153928.html
假设 需要满足条件:
b-a<=k1 (1)
c-b<=k2 (2)
c-a<=k3 (3)
(1)(2)相加 得到不等式c-a<=k1+k2
所以要使条件满足的首要条件就是c-a<=min(k1+k2,k3) 但是可能题目中会有多个条件,不过本质并不会改变,依旧是求最小值,那么我们将a,b,c为点,以k为边权建边,得到一个有向图,求最短路就得到了min;
注意:1.最少每个人分到一个糖果从0填边的时候边权为1,而且要从后面向前填边
2.最终ans用long long存
#include<cstdio>
#include<cstring>
#define maxn 100020
#include<iostream>
#include<queue>
#define LL long long
using namespace std;
queue<int >q;
int n,m,head[maxn*2],tot,vis[maxn],dis[maxn],times[maxn];
struct edge{
int v,w,next;
}e[maxn*4];
void adde(int a,int b,int c){e[tot].v=b,e[tot].w=c,e[tot].next=head[a];head[a]=tot++;}
bool spfa(){
q.push(0),dis[0]=0,times[0]=1;
while(!q.empty()){
int u=q.front();q.pop() ;
vis[u]=0;
for(int i=head[u];i!=-1;i=e[i].next ){
int v=e[i].v ,w=e[i].w;
if(dis[v]<dis[u]+w){
dis[v]=dis[u]+w;
times[v]++;
if(times[v]>=n)return false;
if(!vis[v]){
vis[v]=1;
q.push(v);
}
}
}
}
return true;
}
int main(){
memset(head,-1,sizeof(head));
scanf("%d%d",&n,&m);
for(int pos,b,a,i=1;i<=m;i++){
scanf("%d%d%d",&pos,&a,&b);
if(pos==1){adde(a,b,0),adde(b,a,0);}
else if(pos==2){
if(a==b){printf("-1");}
adde(a,b,1);
}else if(pos==3){
adde(b,a,0);
}else if(pos==4){
if(a==b){printf("-1");return 0;}
adde(b,a,1);break;
}else if(pos==5){
adde(a,b,0);
}
}
for(int i=n;i>=1;i--)adde(0,i,1);
if(!spfa()){printf("-1");return 0;}
LL ans=0;
for(int i=1;i<=n;i++)
ans+=(LL)dis[i];
printf("%lld",ans);
return 0;
}/*
5 7
1 1 2
2 3 2
4 4 1
3 4 5
5 4 5
2 3 5
4 5 1
*/