loj2436 糖果
分析
我们知道对于一个不等式a<b可以将其转化为a+1<=b的形式,在知道这个之后我们便可以将5个关系进行差分约束了,具体的建边方式见代码。注意由于每个人都必须有糖,我们把每个人的初值都赋为1并全部入队。
代码
#include<iostream>
#include<cstdio>
#include<cstring>
#include<string>
#include<algorithm>
#include<cctype>
#include<cmath>
#include<cstdlib>
#include<queue>
#include<ctime>
#include<vector>
#include<set>
#include<map>
#include<stack>
using namespace std;
#define pb push_back
#define mp make_pair
queue<int>q;
vector<pair<int,int> >v[100010];
int d[100010],vis[100010],iq[100010],n;
inline void bad(){
puts("-1");
exit(0);
}
inline void spfa(){
for(int i=1;i<=n;i++){
vis[i]=1;
d[i]=1;
q.push(i);
iq[i]=1;
}
while(!q.empty()){
int x=q.front();
q.pop();iq[x]=0;
for(int i=0;i<v[x].size();i++){
int y=v[x][i].first,z=v[x][i].second;
if(d[y]<d[x]+z){
d[y]=d[x]+z;
vis[y]++;
if(vis[y]>=n)bad();
if(!iq[y]){
q.push(y);
iq[y]=1;
}
}
}
}
}
int main(){
int m,i,j,k;
scanf("%d%d",&n,&m);
for(i=1;i<=m;i++){
int x,y;
scanf("%d%d%d",&k,&x,&y);
if(k==1){
v[x].pb(mp(y,0));
v[y].pb(mp(x,0));
}else if(k==2){
if(x==y)bad();
v[x].pb(mp(y,1));
}else if(k==3){
v[y].pb(mp(x,0));
}else if(k==4){
if(x==y)bad();
v[y].pb(mp(x,1));
}else {
v[x].pb(mp(y,0));
}
}
spfa();
long long ans=0;
for(i=1;i<=n;i++)ans+=(long long)d[i];
printf("%lld\n",ans);
return 0;
}