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;
}
posted @ 2018-08-22 10:36  水题收割者  阅读(151)  评论(0编辑  收藏  举报