小K的农场(差分约束)

来源:互联网 发布:实时大数据平台spark 编辑:程序博客网 时间:2024/05/21 09:13

题目概述
一个数列,数列内元素权值未知,已知m个元素之间的关系信息,以下列三种形式描述:
a 比 b 至少多 c 个单位。
a 比 b 至多多 c 个单位。
a 与 b 相等。
但是,由于小 K 的记忆有些偏差,所以他想要知道存不存在一种情况,使得农场的种植作物数量与他记忆中的所有信息吻合。
如果存在某种情况与小 K 的记忆吻合,输出“Yes”,否则输出“No”。
数据规模:
对于 100% 的数据保证:1 ≤ n,m,a,b,c ≤ 10000。
思路:
这是我做的第一个差分约束的题目,这个题的难点在于如何将三种状态结合起来,有两个方向的思路:一个是至少型,再一个是至多型,在这里我们用至多型来做。
建边方式,CASE 1:ADD(A,B,-C)
CASE 2:ADD(B,A,C)
CASE 3:ADD(A,B,0),ADD(B,A,0)
开始的时候别忘了源点0的建立,然后用一个DFS型SPFA,如果出现负环,则输出无解,反之。
代码如下:

#include<iostream>#include<cstdio>#include<cstdlib>#include<cstring>#include<queue>using namespace std;int i,j,l,m,n,temp;int y[50001],hd[50001],nxt[50001],v[50001];int b[50001],d[50001];int r(){    int aans=0;    char ch=getchar();    while(ch<'0'||ch>'9')    ch=getchar();    while(ch>='0'&&ch<='9')    {        aans*=10;        aans+=ch-'0';        ch=getchar();    }    return aans;}void add(int xx,int yy,int zz){    nxt[++temp]=hd[xx];    y[temp]=yy;    v[temp]=zz;    hd[xx]=temp;}int dfs(int x){    b[x]=1;    for(int i=hd[x];i;i=nxt[i])    {        if(d[x]+v[i]<d[y[i]])        {            d[y[i]]=d[x]+v[i];            if(!b[y[i]])            {                if(!dfs(y[i]))                return 0;            }            else            return 0;        }    }    b[x]=0;    return 1;}int main(){    memset(d,0x7f7f7f,sizeof(d));    n=r(),m=r();    int xx,yy,zz;    for(i=1;i<=n;i++)    {        add(0,i,0);    }    for(i=1;i<=m;i++)    {        xx=r();        if(xx==1)        {            xx=r(),yy=r(),zz=r();            add(xx,yy,-zz);        }        else if(xx==2)        {            xx=r(),yy=r(),zz=r();            add(yy,xx,zz);        }        else        {            xx=r(),yy=r();            add(xx,yy,0);            add(yy,xx,0);        }    }    d[0]=0;    if(!dfs(0))    cout<<"No";    else    cout<<"Yes";    return 0;}/*3 31 1 2 11 2 3 11 3 1 1*/

这里写图片描述

原创粉丝点击