题目描述:
刁姹接到一个任务,为税务部门调查一位商人的账本,看看账本是不是伪造的。账本上记录了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;
}
}