【LOJ】 #2520. 「FJOI2018」所罗门王的宝藏

题解

发现似乎相当于问一个2000个元的方程组有没有解……
然而我懵逼啊……

发现当成图论,两个点之间连一条边,开始BFS,每个点的值赋成边权减另一个点的点权
如果一个环不合法那么肯定无解

代码

#include <iostream>
#include <cstdio>
#include <vector>
#include <algorithm>
#include <cmath>
#include <cstring>
#include <map>
#include <queue>
//#define ivorysi
#define pb push_back
#define space putchar(' ')
#define enter putchar('\n')
#define mp make_pair
#define pb push_back
#define fi first
#define se second
#define mo 974711
#define MAXN 2000005
#define eps 1e-3
#define RG register
#define calc(x) __builtin_popcount(x)
using namespace std;
typedef long long int64;
typedef double db;
template<class T>
void read(T &res) {
    res = 0;char c = getchar();T f = 1;
    while(c < '0' || c > '9') {
    if(c == '-') f = -1;
    c = getchar();
    }
    while(c >= '0' && c <= '9') {
    res = res * 10 + c - '0';
    c = getchar();
    }
    res *= f;
}
template<class T>
void out(T x) {
    if(x < 0) {putchar('-');x = -x;}
    if(x >= 10) {
    out(x / 10);
    }
    putchar('0' + x % 10);
}
struct node {
    int to,next,val;
}E[4005];
int head[2005],sumE,num[2005];
bool vis[2005];
int T,N,M,K;
void add(int u,int v,int c) {
    E[++sumE].to = v;
    E[sumE].next = head[u];
    E[sumE].val = c;
    head[u] = sumE;
}
void addtwo(int u,int v,int c) {
    add(u,v,c);add(v,u,c);
}
queue<int> q;
bool BFS(int x) {
    while(!q.empty()) q.pop();
    q.push(x);
    vis[x] = 1;
    num[x] = 0;
    while(!q.empty()) {
    int u = q.front();q.pop();
    for(int i = head[u] ; i ; i = E[i].next) {
        int v = E[i].to;
        if(!vis[v]) {
        num[v] = E[i].val - num[u];
        vis[v] = 1;
        q.push(v);
        }
        else if(num[u] + num[v] != E[i].val) return false;
    }
    }
    return true;
}
void Init() {
    read(N);read(M);read(K);
    memset(head,0,sizeof(head));sumE = 0;
    memset(vis,0,sizeof(vis));
    int x,y,c;
    for(int i = 1 ; i <= K ; ++i) {
    read(x);read(y);read(c);
    addtwo(x,y + N,c);
    }
}
void Solve() {
    read(T);
    while(T--) {
    Init();
    bool ans = 1;
    for(int i = 1 ; i <= N + M ; ++i) {
        if(!ans) break;
        if(!vis[i]) ans &= BFS(i);
    }
    if(ans) puts("Yes");
    else puts("No");
    }
}
int main() {
#ifdef ivorysi
    freopen("f1.in","r",stdin);
#endif
    Solve();
    return 0;
}

猜你喜欢

转载自www.cnblogs.com/ivorysi/p/9145140.html