BZOJ 2330 糖果

Posted on 2016-05-25 18:48  ziliuziliu  阅读(105)  评论(0编辑  收藏  举报

现学了差分约束。。。

若b>=a+1则a->b:1求最长路。

数据有环,所以不要源点。

为什么要把dis初始化成1?因为每个小朋友至少分到1个。

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<queue>
#define maxv 100500
#define maxe 400500
using namespace std;
struct edge
{
    int v,w,nxt;
}e[maxe];
int n,k,x,a,b,g[maxv],nume=0,dis[maxv],cnt[maxv];
queue <int> q;
bool vis[maxv];
void addedge(int u,int v,int w)
{
    e[++nume].v=v;
    e[nume].w=w;
    e[nume].nxt=g[u];
    g[u]=nume;
}
bool spfa()
{
    for (int i=1;i<=n;i++)
    {
        dis[i]=1;
        q.push(i);
        vis[i]=true;
        cnt[i]=1;
    }
    while (!q.empty())
    {
        int head=q.front();q.pop();vis[head]=false;
        for (int i=g[head];i;i=e[i].nxt)
        {
            int v=e[i].v;
            if (dis[v]<dis[head]+e[i].w)
            {
                dis[v]=dis[head]+e[i].w;
                if (++cnt[v]>=n) return 0;
                else if (!vis[v])
                {
                    vis[v]=true;
                    q.push(v);
                }
            }
        }
    }
    return 1;
}
int main()
{
    scanf("%d%d",&n,&k);
    for (int i=1;i<=k;i++)
    {
        scanf("%d%d%d",&x,&a,&b);
        if (x==1) {addedge(a,b,0);addedge(b,a,0);}
        else if (x==2) 
        {
            if (a==b) {printf("-1\n");return 0;}
            else addedge(a,b,1);
        }
        else if (x==3) addedge(b,a,0);
        else if (x==4)
        {
            if (a==b) {printf("-1\n");return 0;}
            else addedge(b,a,1);
        }
        else addedge(a,b,0);
    }
    if (spfa())
    {
        long long ans=0;
        for (int i=1;i<=n;i++)
            ans+=dis[i];
        printf("%lld\n",ans);
    }    
    else printf("-1\n");
    return 0;
}