bzoj1202

差分约束系统

我们把前缀和看成一个点,每个点之间的关系就是sum[i]-sum[j-1]=?,然后我们拆成sum[i]-sum[j-1]>=?和sum[j-1]-sum[i]>=-?,大于等于号是跑最长路,边从b连向a,边权是符号后面的常数项,然后跑最长路就行了,我们可以用dfs版spfa跑

#include<bits/stdc++.h>
using namespace std;
const int N = 2010;
struct edge {
    int nxt, to, w;
} e[N << 1];
int n, m, cnt = 1;
int head[N], d[N], vis[N], in[N];
void link(int u, int v, int w)
{
    e[++cnt].nxt = head[u];
    head[u] = cnt;
    e[cnt].to = v;
    e[cnt].w = w;
}
int main()
{
    int T;
    scanf("%d", &T);
    while(T--)
    {
        scanf("%d%d", &n, &m);
        memset(head, 0, sizeof(head));
        cnt = 1;
        for(int i = 1; i <= m; ++i)
        {
            int l, r, v;
            scanf("%d%d%d", &l, &r, &v);
            link(l - 1, r, v);
            link(r, l - 1, -v);
        }
        queue<int> q;
        for(int i = 0; i <= n; ++i) q.push(i), in[i] = d[i] = 0, vis[i] = 1;
        bool flag = true;
        while(!q.empty())
        {
            int u = q.front();
            q.pop();
            vis[u] = 0;
            for(int i = head[u]; i; i = e[i].nxt) if(d[e[i].to] < d[u] + e[i].w)
            {
                d[e[i].to] = d[u] + e[i].w;
                if(vis[e[i].to] == 0)
                {
                    ++in[e[i].to];
                    if(in[e[i].to] == n)
                    {
                        puts("false");
                        flag = false;
                        break;
                    }
                    vis[e[i].to] = 1;
                    q.push(e[i].to);
                }
            }
            if(!flag) break;
        }
        if(flag) puts("true");
    }
    return 0;
}

时间: 2024-11-06 19:37:28

bzoj1202的相关文章

【bzoj1202】 HNOI2005—狡猾的商人

http://www.lydsy.com/JudgeOnline/problem.php?id=1202 (题目链接) 题意:给出m段区间和,判断是否存在某段区间与之前读入的区间相矛盾. Solution  裸带权并查集.   代码: // bzoj1202 #include<algorithm> #include<iostream> #include<cstdlib> #include<cstring> #include<cstdio> #in

bzoj1202 [HNOI2005]狡猾的商人

题目链接 并查集 听说有人用差分约束做,我哪天也去试一试 并查集维护后缀和,从前往后合并 注意路径压缩的时候要修改后缀和 1 #include<algorithm> 2 #include<iostream> 3 #include<cstdlib> 4 #include<cstring> 5 #include<cstdio> 6 #include<string> 7 #include<cmath> 8 #include<

BZOJ1202 [HNOI2005]狡猾的商人 并查集维护前缀和

1202: [HNOI2005]狡猾的商人 Time Limit: 10 Sec  Memory Limit: 162 MBSubmit: 1935  Solved: 936[Submit][Status][Discuss] Description 刁姹接到一个任务,为税务部门调查一位商人的账本,看看账本是不是伪造的.账本上记录了n个月以来的收入情况,其中第i 个月的收入额为Ai(i=1,2,3...n-1,n), .当 Ai大于0时表示这个月盈利Ai 元,当 Ai小于0时表示这个月亏损Ai 元

bzoj1202 狡猾的商人

并查集. 传送门 日常抄代码. 太强啦. 想起了当初那道LLJ跑spfa过的题. orz sxy llj大佬 //Twenty #include<cstdio> #include<cstdlib> #include<iostream> #include<algorithm> #include<cmath> #include<cstring> #include<queue> #include<vector> co

【BZOJ1202】【HNOI2005】狡猾的商人 并查集

题解:呃,这个题太耿直了. 还能有负收益,也就是一个区间只需要有某段时间没有确定,或者有重叠,那就"一切皆有可能". 只有边界完全重合的一些区间神马的才能判错. 于是写个耿直的并查集就好了.(可以a~b收益为c,a>b,反正有负收益233) 代码: #include <cstdio> #include <cstring> #include <iostream> #include <algorithm> #define N 105 u

bzoj1202:[HNOI2005]狡猾的商人 【并查集】

Description 刁姹接到一个任务,为税务部门调查一位商人的账本,看看账本是不是伪造的.账本上记录了n个月以来的收入情况,其中第i 个月的收入额为Ai(i=1,2,3...n-1,n), .当 Ai大于0时表示这个月盈利Ai 元,当 Ai小于0时表示这个月亏损Ai 元.所谓一段时间内的总收入,就是这段时间内每个月的收入额的总和. 刁姹的任务是秘密进行的,为了调查商人的账本,她只好跑到商人那里打工.她趁商人不在时去偷看账本,可是她无法将账本偷出来,每次偷看账本时她都只能看某段时间内账本上记录

BZOJ-1202 狡猾的商人

先处理成前缀和关系,然后可以很明显得看得出这是一个差分约束.那么就是最短路问题了. 顺便复习了一下SPFA加SLF优化是怎么写的,也学习到了另一个STL——Deque双向队列. #include <cstdlib> #include <cstdio> #include <cstring> #include <cmath> #include <algorithm> #include <fstream> #include <iost

[HNOI2005][BZOJ1202] 狡猾的商人

1202: [HNOI2005]狡猾的商人 Time Limit: 10 Sec  Memory Limit: 162 MBSubmit: 1863  Solved: 899[Submit][Status][Discuss] Description 刁姹接到一个任务,为税务部门调查一位商人的账本,看看账本是不是伪造的.账本上记录了n个月以来的收入情况,其中第i 个月的收入额为Ai(i=1,2,3...n-1,n), .当 Ai大于0时表示这个月盈利Ai 元,当 Ai小于0时表示这个月亏损Ai 元

[BZOJ1202][HNOI2005]狡猾的商人(并查集+前缀和)

题目描述 传送门 题解 刚开始感觉只有几个区间和另外几个区间都拼成了同一个区间的时候才有可能判false,然后xjblg写出了一个对拍都不过的code然后交上去A了= =可见数据之弱. 网上的正解是并查集,YY了挺久的. 读入区间(l,r,w),如果l和r不在一个集合里,将它们合并:否则判断dis_r-dis_x是否等于w(其中dis_i表示i到它祖先的距离) 代码 xjblg #include<algorithm> #include<iostream> #include<c