BZOJ4500 矩阵

Address


Solution

  • xi x i 表示第 i i +1 1 − 1 操作次数的差, yi y i 表示第 i i +1 1 − 1 操作次数的差。
  • 则对于每个限制 (i,j,c) ( i , j , c ) xi+yj=c x i + y j = c
  • xi+yjc  AND  xi+yjc x i + y j ≥ c     A N D     x i + y j ≤ c
  • 这似乎和一般的差分约束不一样,但可以改写成 xi(yi)c  AND  xi(yi)c x i − ( − y i ) ≥ c     A N D     x i − ( − y i ) ≤ c
  • (yi)xic  AND  xi(yi)c ( − y i ) − x i ≤ − c     A N D     x i − ( − y i ) ≤ c
  • 将对应行列的点连边,则判断存在性即为判断原图是否存在负环。
  • DFS_SPFA D F S _ S P F A 实现即可。

Code

#include <iostream>
#include <cstdio>
#include <algorithm>
#include <cstring>

using namespace std;

const int M = 2005;
int dis[M], T, n, m, K; bool vis[M];

struct Edge
{
    int to, cst; Edge *nxt;
}p[M], *lst[M], *P = p;

inline void Link(int x, int y, int z)
{
    (++P)->nxt = lst[x]; lst[x] = P; P->to = y; P->cst = z;
}

inline int get()
{
    char ch; int res = 0; bool flag = false;
    while (ch = getchar(), !isdigit(ch) && ch != '-');
    (ch == '-' ? flag = true : res = ch ^ 48);
    while (ch = getchar(), isdigit(ch))
        res = res * 10 + ch - 48;
    return flag ? -res : res;
}

inline bool Dfs(int x)
{
    vis[x] = true; int y;
    for (Edge *e = lst[x]; e; e = e->nxt)
        if (dis[y = e->to] > dis[x] + e->cst)
        {
            dis[y] = dis[x] + e->cst;
            if (vis[y] || Dfs(y)) return true;
        }
    return vis[x] = false;
}

int main()
{
    T = get();
    while (T--)
    {
        memset(lst, NULL, sizeof(lst)); P = p;
        n = get(); m = get(); K = get(); int x, y, c;
        while (K--)
        {
            x = get(); y = get(); c = get();
            Link(x, y + n, -c); Link(y + n, x, c);
        } 
        memset(dis, 0, sizeof(dis)); 
        memset(vis, false, sizeof(vis)); bool flag = false;
        for (int i = 1, im = n + m; i <= im && !flag; ++i) flag |= Dfs(i); 
        puts(flag ? "No" : "Yes");
    }
} 
  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值