zoukankan      html  css  js  c++  java
  • 分糖果 5.0升级版

    题目描述

    幼儿园里有N个小朋友,lxhgww老师现在想要给这些小朋友们分配糖果,要求每个小朋友都要分到糖果。但是小朋友们也有嫉妒心,总是会提出一些要求,比如小明不希望小红分到的糖果比他的多,于是在分配糖果的时候,lxhgww需要满足小朋友们的K个要求。幼儿园的糖果总是有限的,lxhgww想知道他至少需要准备多少个糖果,才能使得每个小朋友都能够分到糖果,并且满足小朋友们所有的要求。

    输入输出格式

    输入格式:
    输入的第一行是两个整数N,K。接下来K行,表示这些点需要满足的关系,每行3个数字,X,A,B。如果X=1, 表示第A个小朋友分到的糖果必须和第B个小朋友分到的糖果一样多;如果X=2, 表示第A个小朋友分到的糖果必须少于第B个小朋友分到的糖果;如果X=3, 表示第A个小朋友分到的糖果必须不少于第B个小朋友分到的糖果;如果X=4, 表示第A个小朋友分到的糖果必须多于第B个小朋友分到的糖果;如果X=5, 表示第A个小朋友分到的糖果必须不多于第B个小朋友分到的糖果;

    输出格式:
    输出一行,表示lxhgww老师至少需要准备的糖果数,如果不能满足小朋友们的所有要求,就输出-1。

    题解

    裸的差分约束系统啊!!
    只有一点需要注意 就是每个人都要发糖 也就是说每个人都至少发一块糖 所以源点给每个点连边的时候连权值为1的边 不是权值为0的边
    最后说个题外话 这个题原数据有一个点是一个十万的链 有个玄学方法可以解决 就是源点连边的时候倒着加边(从n加到1)
    另外有一个点存在a=b的情况 x=2和x=4的情况下如果a=b直接输出-1

    代码

    type
      arr=record
            x,y,w,next:longint;
          end;
    var
      ans:int64;
      n,k,nm:longint;
      a:array [0..800001] of arr;
      st,ls,len:array [0..400001] of longint;
      d:array [0..400001] of int64;
      v:array [0..400001] of boolean;
      bo:boolean;
    procedure add(u,v,z:longint);
    begin
      inc(nm);
      with a[nm] do
        begin
          x:=u; y:=v; w:=z;
          next:=ls[u];
          ls[u]:=nm;
        end;
    end;
    
    procedure init;
    var
      i,u,v,z:longint;
    begin
      readln(n,k);
      for k:=1 to k do
        begin
          readln(z,u,v);
          case z of
            1:begin
                add(u,v,0);
                add(v,u,0);
              end;
            2:begin
                if u=v then
                  begin
                    write('-1');
                    halt;
                  end;
                add(u,v,1);
              end;
            3:add(v,u,0);
            4:begin
                if u=v then
                  begin
                    write('-1');
                    halt;
                  end;
                add(v,u,1);
              end;
            5:add(u,v,0);
          end;
        end;
      for i:=1 to n do
        add(0,i,1);
      bo:=false;
    end;
    
    procedure spfa;
    var
      i,t,x:longint;
    begin
      fillchar(d,sizeof(d),0);
      t:=1;
      d[1]:=0; st[1]:=0; v[0]:=true;
      while t<>0 do
        begin
          x:=st[t]; dec(t);
          i:=ls[x];
          while i<>0 do
            begin
              if d[a[i].y]<d[x]+a[i].w then
                begin
                  d[a[i].y]:=d[x]+a[i].w;
                  if not v[a[i].y] then
                    begin
                      v[a[i].y]:=true;
                      inc(t);
                      st[t]:=a[i].y;
                      inc(len[a[i].y]);
                    end;
                  if len[a[i].y]>n then
                    begin
                      bo:=true;
                      exit;
                    end;
                end;
              i:=a[i].next;
            end;
          v[x]:=false;
        end;
    end;
    
    procedure print;
    var
      i:longint;
    begin
      ans:=0;
      for i:=1 to n do
        ans:=ans+d[i];
      write(ans);
    end;
    
    begin
      init;
      spfa;
      if bo then write('-1') else print;
    end.
  • 相关阅读:
    java中next()、nextInt()、nextLine()区别
    原码、反码、补码及移位运算
    微信小程序开发流程(适用于新手学习)
    Dubbo 常用的容错机制
    分布式系统性能注意点
    陌上人如玉,公子世无双!
    五步工作法
    四个凡是
    Javacpu 和内存问题排查步骤
    开启JMC功能
  • 原文地址:https://www.cnblogs.com/zyx-crying/p/9319540.html
Copyright © 2011-2022 走看看