P3275_[SCOI2011]糖果灾区糖果分发成功

Posted lemir3

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了P3275_[SCOI2011]糖果灾区糖果分发成功相关的知识,希望对你有一定的参考价值。

题面

这是一道用差分约束的题解.

但是这道题卡SPFA

有5个差分不等式,其实很好推的.

1.a=b,推出a-b<=0与b-a<=0,于是以a向b建一条权值为0的边,以b向a建一条权值为0的边.(相等的关系都要建2条边的)

2.a<b,把它变成a+1<=b,推出b-a<=1,于是以a向b建一条权值为1的边.

3.a<=b,推出a-b<=0,以b向a建一条权值为0的边.

4.a>b,把它变成a-1>=b,推出b-a<=1,于是以b向a建一条权值为1的边.

5.a>=b,推出b-a<=0,以a前b建一条权值为0的边.

然后用一个超级源点连接,源点向每个边的权值都为1,因为每个灾民小朋友都要分至少一个糖.

用不等式表达就是a-b>=1.b为源点,自然没有糖,a至少有一个糖.

再用一个数组存一下节点被遍历的次数,如果大于n+1(所有节点+超级源点)就说明存在环了,具体请见这篇博客.

什么?你说我没倒序存边?

代码见下,为了显得成分多加了O3,请自行忽略1~49行.


#pragma GCC diagnostic error "-std=c++11"
#pragma GCC target("sse2")
#pragma GCC optimize(3)
#pragma GCC target("avx")
#pragma GCC optimize("Ofast")
#pragma GCC optimize("inline")
#pragma GCC optimize("-fgcse")
#pragma GCC optimize("-fgcse-lm")
#pragma GCC optimize("-fipa-sra")
#pragma GCC optimize("-ftree-pre")
#pragma GCC optimize("-ftree-vrp")
#pragma GCC optimize("-fpeephole2")
#pragma GCC optimize("-ffast-math")
#pragma GCC optimize("-fsched-spec")
#pragma GCC optimize("unroll-loops")
#pragma GCC optimize("-falign-jumps")
#pragma GCC optimize("-falign-loops")
#pragma GCC optimize("-falign-labels")
#pragma GCC optimize("-fdevirtualize")
#pragma GCC optimize("-fcaller-saves")
#pragma GCC optimize("-fcrossjumping")
#pragma GCC optimize("-fthread-jumps")
#pragma GCC optimize("-funroll-loops")
#pragma GCC optimize("-fwhole-program")
#pragma GCC optimize("-freorder-blocks")
#pragma GCC optimize("-fschedule-insns")
#pragma GCC optimize("inline-functions")
#pragma GCC optimize("-ftree-tail-merge")
#pragma GCC optimize("-fschedule-insns2")
#pragma GCC optimize("-fstrict-aliasing")
#pragma GCC optimize("-fstrict-overflow")
#pragma GCC optimize("-falign-functions")
#pragma GCC optimize("-fcse-skip-blocks")
#pragma GCC optimize("-fcse-follow-jumps")
#pragma GCC optimize("-fsched-interblock")
#pragma GCC optimize("-fpartial-inlining")
#pragma GCC optimize("no-stack-protector")
#pragma GCC optimize("-freorder-functions")
#pragma GCC optimize("-findirect-inlining")
#pragma GCC optimize("-fhoist-adjacent-loads")
#pragma GCC optimize("-frerun-cse-after-loop")
#pragma GCC optimize("inline-small-functions")
#pragma GCC optimize("-finline-small-functions")
#pragma GCC optimize("-ftree-switch-conversion")
#pragma GCC optimize("-foptimize-sibling-calls")
#pragma GCC optimize("-fexpensive-optimizations")
#pragma GCC optimize("-funsafe-loop-optimizations")
#pragma GCC optimize("inline-functions-called-once")
#pragma GCC optimize("-fdelete-null-pointer-checks")

#include<iostream>
#include<cstdio>
#include<algorithm>
#include<queue>
#include<iomanip>
#include<cstring>
#include<stack>

using namespace std;

stack<int>q;

struct edge

  int val,next,to;
e[300010];

int n,k,size;
long long ans;
int head[100010],dis[100010],in[100010];
bool flag[100010];

void edge_add(int,int,int);
void SPFA();

int main()

  memset(head,-1,sizeof(head));
  scanf("%d%d",&n,&k);
  for(int i=1;i<=k;i++)
  
    int o,a,b;
    scanf("%d%d%d",&o,&a,&b);
    if(o==1)
    
      edge_add(b,a,0);
      edge_add(a,b,0);
    
    if(o==2)
    
      edge_add(a,b,1);
    
    if(o==3)
    
      edge_add(b,a,0);
    
    if(o==4)
    
      edge_add(b,a,1);
    
    if(o==5)
    
      edge_add(a,b,0);
    
  
  for(int i=1;i<=n;i++)edge_add(0,i,1);
  SPFA();
  for(int i=1;i<=n;i++)ans+=dis[i];
  printf("%lld\\n",ans);
return 0;


void edge_add(int from,int to,int val)

  e[++size].to=to;
  e[size].val=val;
  e[size].next=head[from];
  head[from]=size;


void SPFA()

  memset(dis,-0x3f,sizeof(dis));
  memset(flag,false,sizeof(flag));
  memset(in,0,sizeof(in));
  q.push(0);
  dis[0]=0;
  flag[0]=true;
  while(!q.empty())
  
    int from=q.top();
    q.pop();
    flag[from]=false;
    in[from]++;
    if(in[from]>n+1)
    
      printf("-1\\n");
      exit(0);
    
    for(int i=head[from];i!=-1;i=e[i].next)
    
      int to=e[i].to;
      int val=e[i].val;
      if(dis[to]<dis[from]+val)
      
        dis[to]=dis[from]+val;
        if(flag[to]==false)
        
          q.push(to);
          flag[to]=true;
        
      
    
  

以上是关于P3275_[SCOI2011]糖果灾区糖果分发成功的主要内容,如果未能解决你的问题,请参考以下文章

[luogu P3275] [SCOI2011]糖果

P3275 [SCOI2011]糖果

P3275 [SCOI2011]糖果

洛谷P3275 [SCOI2011]糖果

[luoguP3275] [SCOI2011]糖果(差分约束)

P3275 [SCOI2011]糖果