[SCOI2011]糖果 (差分约束)

题目链接

Solution

差分约束乱搞就好了.
需要注意的地方:

  • 对于大于等于的直接联等于,应为等于,因为对于我满足条件而言,等于总是最好的.
  • 对于等于的,注意要建双向边.
  • 然后要开 \(long~long\) .

然后按照套路搞就是了.

Code

// luogu-judger-enable-o2
#include<bits/stdc++.h>
using namespace std;
const int maxn=100008;

struct sj{int to,next,w;}a[maxn*2];
int head[maxn],size,v[maxn];
int dis[maxn],n,m,cnt[maxn];

void add(int x,int y,int w)
{
    a[++size].to=y;
    a[size].next=head[x];
    head[x]=size;
    a[size].w=w;
}

queue<int>q;
void SPFA()
{
    while(!q.empty())
    {
        int x=q.front(); q.pop();
        cnt[x]++;
        if(cnt[x]>=n){cout<<-1<<endl;exit(0);}
        for(int i=head[x];i;i=a[i].next)
        {
            int tt=a[i].to;
            if(dis[tt]<dis[x]+a[i].w)
            {
                dis[tt]=dis[x]+a[i].w;
                if(!v[tt])
                q.push(tt),v[tt]=1;
            }
        }
        v[x]=0;
    }
}

int main()
{
    scanf("%d%d",&n,&m);
    for(int i=1;i<=m;i++)
    {
        int opt,x,y;
        scanf("%d%d%d",&opt,&x,&y);
        if(opt==1) add(x,y,0),add(y,x,0);
        if(opt==2) add(x,y,1);
        if(opt==3) add(y,x,0);
        if(opt==4) add(y,x,1);
        if(opt==5) add(x,y,0);
    }
    memset(dis,-127,sizeof(dis));
    for(int i=1;i<=n;i++)
    q.push(i),dis[i]=1,v[i]=1;
    SPFA();
    /*int kk=192608173;
    for(int i=1;i<=n;i++)
        kk=min(kk,dis[i]);*/
    long long ans=0;
    for(int i=1;i<=n;i++)
    ans+=dis[i];
    if(ans<n)ans=-1;
    //cout<<dis[i]<<endl,ans+=(dis[i]-kk);
    cout<<ans<<endl;
}

posted @ 2018-09-06 19:59  Kevin_naticl  阅读(211)  评论(0编辑  收藏  举报