P3275 糖果(差分约束)

//2020/8/24/21:07
#include <cstdio>
#include <iostream>
#include <cmath>
#include <string>
#include <cstring>
#include <algorithm>
#include <vector>
#include<queue>
using namespace std;
typedef long long ll;
const int N = 3e5 + 10;
const int INF = 0x3f3f3f3f;
//
inline int read()
{
    char c=getchar();
    int x=0,f=1;
    while(!isdigit(c)){if(c=='-')f=-1;c=getchar();}
    while(isdigit(c))x=(x<<3)+(x<<1)+(c^48),c=getchar();
    return x*f;
}


int n, m;
int head[N], cnt = 0;
int to[N], nxt[N], c[N];
int num[N], dis[N]; bool vis[N]; //mark[N];

inline void add(int u, int v, int w){
   to[cnt] = v, c[cnt] = w, nxt[cnt] = head[u], head[u] = cnt ++;
   // to[cnt] = u, c[cnt] = w, nxt[cnt] = head[u], head[u] = cnt ++;
}

bool SPFA(int st){
    queue<int> q;
    for(int i = 0; i <= n; ++ i){
        vis[i] = false; num[i] = 0; dis[i] = INF;
    }
    q.push(st); vis[st] = true; num[st] = 1; dis[st] = 0;
    while(q.size()){
        int u = q.front(); q.pop();
        vis[u] = false;
        for(int i = head[u]; i != -1; i = nxt[i]){
            int v = to[i], w = c[i];
            if(dis[v] > dis[u] + w){
                dis[v] = dis[u] + w;
                if(!vis[v]){
                    q.push(v); vis[v] = true;
                    if(++ num[v] >= n) return false;
                }
            }
        }
    }
    return true;
}


int main()
{
    n = read(), m = read();
    cnt = 0;
    for(int i = 0; i <= n; ++ i) head[i] = -1;
    while(m --){
        int op, x, y;
        op = read();
        if(op == 1){
            x = read(), y = read();
            add(x, y, 0); add(y, x, 0);
        }
        else if(op == 2){
            x = read(), y = read();
            if(x == y){
                printf("-1\n"); return 0;
            }
            add(x, y, -1);
        }
        else if(op == 3){
            x = read(), y = read();
            add(y, x, 0);
        }
        else if(op == 4){
            x = read(), y = read();
            if(x == y){
                printf("-1\n"); return 0;
            }
            add(y, x, -1);
        }
        else{
            x = read(), y = read();
            add(x, y, 0);
        }
    }
    
    for(int i = n; i >= 1; -- i){
        add(0, i, -1);
    }
    if(SPFA(0)){
        ll res = 0;
        for(int i = 1; i <= n; ++ i) {
            res -= dis[i];
        }
        printf("%lld\n",res);
    }
    else printf("-1\n");
    return 0;
}
posted @ 2020-08-24 21:08  A_sc  阅读(89)  评论(0编辑  收藏  举报