[SCOI2011]糖果

Posted szmssf

tags:

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

题目传送门

对于一个刚接触差分约束系统的OIer来说,这算是一道细节比较多,也比较难的题。首先就是这道题有5种不同的约束条件,对于条件1,3,5直接按照差分条件建边即可,条件2,4要先移项,再建边。之后再求单源最长路,好不容易做出来后你就会发现数据卡SPFA!!!!这里可以加两个小小的优化:1)当a,b严格大于或小于时,他们不能为同一个人,先预判出来可以节省大量时间(不加#5会TLE)。还有要倒序建边,,,(没有任何道理,倒序就能AC,正序会TLE)

参考程序如下:

#include<iostream>
#include<cstring>
#include<queue>
#include<cstdio>
using namespace std;
long long n,m,dist[350005],v[350005],w[350005],nxt[350005],head[350005],cnt,x,a,b,ring[350005];
bool vis[350005];
inline int read()

    int f=1,x=0;
    char s=getchar();
    while(s<‘0‘||s>‘9‘)if(s==‘-‘)f=-1;s=getchar();
    while(s>=‘0‘&&s<=‘9‘)x=x*10+s-‘0‘;s=getchar();
    return x*f;

inline void add(int a,int b,int c)

    v[++cnt]=b;
    w[cnt]=c;
    nxt[cnt]=head[a];
    head[a]=cnt;

inline bool spfa(int node)

    queue<int>q;
    q.push(node);
    vis[node]=1;
    while(!q.empty())
    
        int c=q.front();
        q.pop();
        vis[c]=0;
        ring[c]++;
        //cout<<c<<endl;
        if(ring[c]==n)return 0;
        for(int i=head[c];i;i=nxt[i])
        
            int y=v[i];
            //cout<<"-------------------CJXGBH---------------------"<<endl;
            //cout<<dist[y]<<" "<<dist[c]<<" "<<w[i]<<endl;
            if(dist[y]<dist[c]+w[i])
            
                dist[y]=dist[c]+w[i];
                if(!vis[y])
                
                    q.push(y);
                    vis[y]=1;
                
            
        
    
    return 1;

int main()

	//freopen("1.in","r",stdin);
    n=read();m=read();
    for(int i=1;i<=m;i++)
    
        x=read();a=read();b=read();
        if(x==1)
        
			add(a,b,0);
			add(b,a,0);	
        
        if(x==2)
        
        	add(a,b,1);
        	if(a==b)
        	
        		cout<<"-1";
        		return 0;
			
        	
        if(x==3)
		
			add(b,a,0);
        
        if(x==4)
        
    		add(b,a,1); 
			if(a==b)
			
				cout<<"-1";
				return 0;
			   	
		
		if(x==5)
		
			add(a,b,0);
		
    
    for(int i=n;i>=1;i--)
    
    	add(0,i,1);
	
    if(!spfa(0))
	
		cout<<"-1";
		return 0;	
	
    long long ans=0;
	for(int i=1;i<=n;i++)ans+=dist[i];
	cout<<ans; 
    return 0;

  

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

bzoj2330 [SCOI2011]糖果

[luogu P3275] [SCOI2011]糖果

差分约束 bzoj2330[SCOI2011]糖果

bzoj2330: [SCOI2011]糖果(差分约束)

bzoj 2330: [SCOI2011]糖果

bzoj 2330[SCOI2011]糖果 - 差分约束