bzoj1202:狡猾的商人

题目描述:

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

大致思路:

从s月到t月的记录,就是查找这个区间结果之间是否存在矛盾。也就有了一个想法,s,t,v就像当与在s节点和t节点之间连一条边,权值为v,这样的话对于矛盾的判断就转换成了类似floyd算法了,如果s到t没有可行路,就加入s,t,如果存在,比较权值和v的大小,如果不相等就是存在矛盾。

代码:

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

using namespace std;

const int inf = 0x3f3f3f3f;
int g[101][101];

int main() {
    int w;
    cin>>w;
    while (w--) {
        int n,m;
        cin>>n>>m;
        memset(g,inf,sizeof(g));
        for (int i = 0; i < m; i++) {
            int s,t,v;
            scanf("%d%d%d",&s,&t,&v);
            g[s][t] = v;
        }
        bool f = true;
        for (int k = 1; k <= n; k++) {
            for (int i = 1; i <= n; i++) {
                if (i > k-1) break;
                for (int j = i+1; j <= n; j++) {
                    if (g[i][k-1] != inf && g[k][j] != inf)
                        if (g[i][j] == inf) g[i][j] = g[i][k-1] + g[k][j];
                        else {
                            if (g[i][j] != g[i][k-1] + g[k][j]) f = false;
                        }
                }
                if (!f) break;
            }
            if (!f) break;
        }
        if (f) cout<<"true"<<endl;
        else cout<<"false"<<endl;
    }
}


发布了90 篇原创文章 · 获赞 0 · 访问量 4万+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章