題目描述:
刁奼接到一個任務,爲稅務部門調查一位商人的賬本,看看賬本是不是僞造的。賬本上記錄了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;
}
}