zoukankan      html  css  js  c++  java
  • 洛谷P3275 [SCOI2011]糖果 题解

    题目链接:

    https://www.luogu.org/problemnew/show/P3275

    分析:

    本题就是一个裸的差分约束。


    核心:

    x=1x=1时,a=b,a>b,b>aa=b,a->b,b->a,连边权值为00

    x=2x=2时,a<ba<b,此时我们用整数这个性质,于是可知ab1aleq b-1,a>ba->b,权值为11

    x=3x=3时,bableq a,bbaa连权值为00

    x=4x=4时,b<ab<a,此时我们用整数这个性质,于是可知ba1bleq a-1,b>ab->a,权值为11

    x=5x=5时,abaleq b,aabb连权值为00


    然后就是因为每个人都有糖,所以00ii连边,权值为1(1i<=n)1(1leq i<=n)

    这里很多的存储方式为了避免链的超时,需要倒序,但是这里的vector邻接表存储倒序反而超时!


    提醒:

    x=2x=2x=4x=4时,可能出现A=BA=B的情况,此时要特判输1-1

    数据较大,要开longlong longlong

    代码:

    #include<cstdio>
    #include<vector>
    #include<queue> 
    using namespace std;
    struct edge
    {
    	int to,val;
    	edge(int _to,int _val)
    	{
    		to=_to;
    		val=_val; 
    	}
    };
    long long dis[300005];
    int vis[300005],tot[300005];
    vector<edge>e[300005];
    void add(int x,int y,int w)
    {
    	e[x].push_back(edge(y,w));
    }
    int main()
    {
    	queue<int>q;
    	int n,k,X,A,B;
    	scanf("%d%d",&n,&k);
    	for(int i=1;i<=k;i++)
    	{
    		scanf("%d%d%d",&X,&A,&B);
    		if(X==1)
    		{
    			add(A,B,0);
    			add(B,A,0);
    		}
    		else
    		if(X==2)
    		{
    			if(A==B)
    			{
    				printf("-1
    ");
    				return 0;
    			}
    			add(A,B,1);
    		}
    		else
    		if(X==3)
    		{
    			add(B,A,0);
    		}
    		else
    		if(X==4)
    		{
    			if(A==B)
    			{
    				printf("-1
    ");
    				return 0;
    			}
    			add(B,A,1);
    		}
    		else
    		add(A,B,0);
    	}
    	for(int i=1;i<=n;i++)
    	{
    		add(0,i,1);
    	}
    	vis[0]=1;
    	q.push(0);
    	while(!q.empty())
    	{
    		int x=q.front();q.pop();
    		vis[x]=0;
    		for(int i=0;i<e[x].size();i++)
    		{
    			int y=e[x][i].to;
    			if(dis[y]<dis[x]+e[x][i].val)
    			{
    				dis[y]=dis[x]+e[x][i].val;
    				if(vis[y]==0)
    				{
    					vis[y]=1;
    					q.push(y);
    					tot[y]++;
    					if(tot[y]>n)
    					{
    						printf("-1
    ");
    						return 0;
    					}
    					
    				}
    			}
    		}
    	}
    	long long ans=0;
    	for(int i=1;i<=n;i++)
    	{
    		ans+=dis[i];
    	}
    	printf("%lld
    ",ans);
    	return 0;
    }
    
  • 相关阅读:
    java核心技术卷上学习笔记
    个人作业——软件工程实践总结作业
    个人作业——软件产品案例分析
    软件工程作业-结对编程 2.0
    软件工程作业-结对编程 1.0
    软件工程作业2.0
    软件工程作业1.0
    《面向对象程序设计》c++第六次作业___calculator SE
    面向对象程序设计作业 6.1~6.4
    面向对象程序设计作业 5.1~5.5
  • 原文地址:https://www.cnblogs.com/ShineEternal/p/10834225.html
Copyright © 2011-2022 走看看