【洛谷P2294】[HNOI2005] 狡猾的商人

本来我是不想发这道题的 占空间

但是呢 鉴于我被卡了半个上午 重敲了三次之后 我开始醒悟了
这tm是个什么玩意
我们放题目吧:

P2294 [HNOI2005] 狡猾的商人

题目描述

刁姹接到一个任务,为税务部门调查一位商人的账本,看看账本是不是伪造的。账本上记录了 \(n\) 个月以来的收入情况,其中第 \(i\) 个月的收入额为 \(a_i\)\(i=1,2,\ldots,n-1,n\)。当 \(a_i>0\) 时表示这个月盈利 \(a_i\) 元,当 \(a_i<0\) 时表示这个月亏损 \(|a_i|\) 元。所谓一段时间内的总收入,就是这段时间内每个月的收入额的总和。

刁姹的任务是秘密进行的,为了调查商人的账本,她只好跑到商人那里打工。她趁商人不在时去偷看账本,可是她无法将账本偷出来,每次偷看账本时她都只能看某段时间内账本上记录的收入情况,并且她只能记住这段时间内的总收入。

现在,姹总共偷看了 \(m\) 次账本,当然也就记住了 \(m\) 段时间内的总收入,你的任务是根据记住的这些信息来判断账本是不是假的。

输入格式

第一行为一个正整数 \(w\),其中 \(w<100\),表示有 \(w\) 组数据,即 \(w\) 个账本,需要你判断。

每组数据的第一行为两个正整数 \(n\)\(m\),其中 \(n<100,m<1000\),分别表示对应的账本记录了多少个月的收入情况以及偷看了多少次账本。

接下来的 \(m\) 行表示刁姹偷看 \(m\) 次账本后记住的 \(m\) 条信息,每条信息占一行,有三个整数 \(s,t\)\(v\),表示从第 \(s\) 个月到第 \(t\) 个月(包含第 \(t\) 个月)的总收入为 \(v\),这里假设 \(s\) 总是小于等于 \(t\)

输出格式

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

输入输出样例 #1

输入 #1

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

输出 #1

true
false

Solution

就是简单的差分约束模版题吧
几个要注意的点
第一,最短路跑不过就跑最长路 dis赋值是-0x3f
第二,跟codeforces一样,多测题要清空 这题不像cf那么恶心会卡memset 直接清完事
第三,把这道题看成前缀和,所以建边的时候要建x-1,y
第四,双向建边,因为是等于
第五,人格启动!()
第五,因为有前缀和,超级源点不能建在0,要建在n+1
第六,因为有0~n+1这(n+2)个点 所以cnt判断的时候要判断成n+2
下面看代码:

#include<bits/stdc++.h>
#define ll long long
#define ull unsigned long long
#define maxm 10005
#define maxn 1005
using namespace std;
int t,n,m,tot;
int x,y,z;
int head[maxm],nex[maxm],edge[maxm],ver[maxm];
int d[maxn],vis[maxn],cnt[maxn];
queue<int>q;
void add(int x,int y,int z){
    ver[++tot]=y;
    edge[tot]=z;
    nex[tot]=head[x];
    head[x]=tot;
}
void clear(){
    while(!q.empty()) q.pop();
    memset(d,-0x3f,sizeof(d));
    memset(vis,0,sizeof(vis));
    memset(cnt,0,sizeof(cnt));
    memset(head,0,sizeof(head));
    memset(nex,0,sizeof(nex));
    memset(edge,0,sizeof(edge));
    memset(ver,0,sizeof(ver));
    tot=0;
}
bool spfa(int sx){
    d[sx]=0;
    vis[sx]=1;
    q.push(sx);
    while(!q.empty()){
        int x=q.front();q.pop();
        vis[x]=0;
        for(int i=head[x];i;i=nex[i]){
            int y=ver[i],z=edge[i];
            if(d[y]<d[x]+z){
                d[y]=d[x]+z;
                if(!vis[y]){
                    cnt[y]++;
                    if(cnt[y]>=n+2){
                        return true;
                    }
                    vis[y]=1;
                    q.push(y);
                }
            }
        }
    }
    return false;
}
int main(){
    scanf("%d",&t);
    while(t--){
        clear();
        scanf("%d%d",&n,&m);
        for(int i=1;i<=m;i++){
            scanf("%d%d%d",&x,&y,&z);
            add(x-1,y,z);
            add(y,x-1,-z);
        }
        for(int i=0;i<=n;i++){
            add(n+1,i,0);
        }
        if(spfa(n+1)) printf("false\n");
        else printf("true\n");
    }
    system("pause");
    return 0;
}

刚退出去发现忘放图了()
image

posted @ 2025-04-04 10:49  elainafan  阅读(18)  评论(0)    收藏  举报