码迷,mamicode.com
首页 > 其他好文 > 详细

[SCOI2011]糖果

时间:2019-06-24 22:43:50      阅读:127      评论:0      收藏:0      [点我收藏+]

标签:不同的   大量   pac   ret   string   --   show   har   void   

题目传送门

对于一个刚接触差分约束系统的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]糖果

标签:不同的   大量   pac   ret   string   --   show   har   void   

原文地址:https://www.cnblogs.com/szmssf/p/11079874.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!