|BZOJ 2330|差分约束|[SCOI2011]糖果

来源:互联网 发布:300451 创业软件股吧 编辑:程序博客网 时间:2024/05/06 05:09

BZOJ传送门
差分约束。
裸题不讲了。可以看我的差分约束学习笔记。
注意这题直接把所有点加进来做,否则TLE,还要开long long

#include<cstdio>  #include<algorithm>  #include<cstring>  #include<vector>#include<queue>#define ms(i,j) memset(i,j, sizeof i);#define ll long longusing namespace std;const int MAXN = 100000 + 5; ll n,k;struct edge{    ll u,v,c;}E[MAXN*4];ll e_num = 0;vector<ll> G[MAXN];void addE(ll u, ll v, ll c){    e_num++;    E[e_num].u = u;    E[e_num].v = v;    E[e_num].c = c;    G[u].push_back(e_num);}ll dis[MAXN];ll vi[MAXN];ll cir[MAXN];ll spfa(){    queue<ll> q;    for (ll i=1;i<=n;i++)    {        dis[i] = 1;        vi[i] = false;        cir[i] = 1;        q.push(i);    }    while (!q.empty())    {        ll r = q.front(); q.pop();        for (ll i=0;i<G[r].size();i++)        {            edge ed = E[G[r][i]];            vi[ed.v] = false;            if (dis[ed.v]<dis[r]+ed.c)            {                dis[ed.v] = dis[r]+ed.c;                if (!vi[ed.v])                {                    cir[i]++;                    if (cir[i]>n)                    {                        return false;                    }                    vi[ed.v] = true;                    q.push(ed.v);                }            }        }    }    return true;}int main()  {      scanf("%d%d", &n, &k);    for (ll i=1;i<=k;i++)    {        ll x,a,b;        scanf("%lld%lld%lld", &x, &a, &b);        switch(x)        {            case 1: addE(a,b,0); addE(b,a,0); break;            case 2: if (a==b) {printf("-1\n");return 0;} addE(a,b,1); break;            case 3: addE(b,a,0); break;            case 4: if (a==b) {printf("-1\n");return 0;} addE(b,a,1); break;            case 5: addE(a,b,0); break;        }    }     if(!spfa()) printf("-1\n"); else         {            ll ans = 0;            for (ll i=1;i<=n;i++)            {                ans += dis[i];            }            printf("%lld\n", ans);        }       return 0;  }  
0 0