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

1202: [HNOI2005]狡猾的商人

Time Limit: 10 Sec  Memory Limit: 162 MB
Submit: 1935  Solved: 936
[Submit][Status][Discuss]

Description

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

Input

第一行为一个正整数w,其中w < 100,表示有w组数据,即w个账本,需要你判断。每组数据的第一行为两个正整数n和m,其中n < 100,m < 1000,分别表示对应的账本记录了多少个月的收入情况以及偷看了多少次账本。接下来的m行表示刁姹偷看m次账本后记住的m条信息,每条信息占一行,有三个整数s,t和v,表示从第s个月到第t个月(包含第t个月)的总收入为v,这里假设s总是小于等于t。

Output

包含w行,每行是true或false,其中第i行为true当且仅当第i组数据,即第i个账本不是假的;第i行为false当且仅当第i组数据,即第i个账本是假的。

Sample Input

2
3 3
1 2 10
1 3 -5
3 3 -15
5 3
1 5 100
3 5 50
1 2 51

Sample Output

true
false

//1085422276
#include<iostream>
#include<cstdio>
#include<cstring>
#include<string>
#include<algorithm>
#include<queue>
#include<cmath>
#include<map>
#include<bitset>
#include<set>
#include<vector>
using namespace std ;
typedef long long ll;
#define mem(a) memset(a,0,sizeof(a))
#define meminf(a) memset(a,127,sizeof(a));
#define memfy(a) memset(a,-1,sizeof(a))
#define TS printf("111111\n");
#define FOR(i,a,b) for( int i=a;i<=b;i++)
#define FORJ(i,a,b) for(int i=a;i>=b;i--)
#define READ(a,b,c) scanf("%d%d%d",&a,&b,&c)
#define mod 1000000007
#define maxn 106
inline ll read()
{
    ll x=0,f=1;
    char ch=getchar();
    while(ch<‘0‘||ch>‘9‘)
    {
        if(ch==‘-‘)f=-1;
        ch=getchar();
    }
    while(ch>=‘0‘&&ch<=‘9‘)
    {
        x=x*10+ch-‘0‘;
        ch=getchar();
    }
    return x*f;
}
//****************************************
int n,m,parent[maxn],v[maxn];
void init()
{
    FOR(i,0,n)parent[i]=i;mem(v);
}
int finds(int x)
{
    if(x==parent[x])return x;
    int t=parent[x];
    parent[x]=finds(parent[x]);
    v[x]+=v[t];
    return parent[x];

}
int main()
{

    int T=read();
     while(T--)
     {
         n=read();
         m=read();
         init();
         int flag=0,x,y,w;
         FOR(i,1,m)
         {
             scanf("%d%d%d",&x,&y,&w);
             int fx=finds(x-1);
             int fy=finds(y);
             if(fx!=fy)
             {
                 parent[fx]=fy;
                 v[fx]=v[y]-v[x-1]+w;
             }else if(v[x-1]-v[y]!=w)flag=1;
         }
         if(flag)printf("false\n");
         else printf("true\n");
     }
    return 0;
}

代码

时间: 2024-08-05 07:04:58

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

bzoj1202: [HNOI2005]狡猾的商人(并查集 差分约束)

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

bzoj 1202: [HNOI2005]狡猾的商人 并查集好题

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

BZOJ 1202 HNOI2005 狡猾的商人 并查集

题目大意:给定一个序列,m次给出一段区间的和,求这个序列是否合法 第一眼看还以为是差分约束- - [x,y]区间内和为z等价于sum[y]-sum[x-1]=z 用并查集来维护这个关系即可 #include <cstdio> #include <cstring> #include <iostream> #include <algorithm> #define M 110 using namespace std; int n,m; int fa[M],f[M]

bzoj1202: [HNOI2005]狡猾的商人(差分约束)

1202: [HNOI2005]狡猾的商人 题目:传送门 题解: 据说是带权并查集!蒟蒻不会啊!!! 可是听说lxj大佬用差分约束A了,于是开始一通乱搞. 设s[i]为前i个月的总收益,那么很容易就可以推出约束条件了啊:  s[x-1]>=s[y]-c s[y]>=s[x-1]+c 然后就可以去跑最长路了 吐槽: lxj大佬推出来的条件竟然是两个小于等于号:s[x-1]<=s[y]-c s[y]<=s[x-1]+c 然后跑最短路也A了,表示很玄学qwq 代码: 1 #include

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】狡猾的商人 并查集

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

[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

BZOJ 1202 [HNOI2005]狡猾的商人(并查集)

[题目链接] http://www.lydsy.com/JudgeOnline/problem.php?id=1202 [题目大意] 给出一些区间和的数值,问是否存在矛盾 [题解] 用并查集维护前缀和之间的距离,每个节点保存到根节点的数值差, 如果保存的数值差的差与前缀和之差不相等,则矛盾 [代码] #include <cstdio> #include <algorithm> using namespace std; const int N=110; int n,m,f[N],d[

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

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