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萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章