BZOJ 1202 狡猾的商人

題面:
刁奼接到⼀個任務,爲稅務部⻔調查⼀位商⼈的賬本,看看賬本是不是僞造的。賬本上記錄了n 個⽉以來的收⼊情況,其中第i 個⽉的收⼊額爲Ai(i=1...n) 。當Ai0 時表示這個⽉盈利Ai 元,當Ai0 時表示這個⽉虧損Ai 元。所謂⼀段時間內的總收⼊,就是這段時間內每個⽉的收⼊額的總和。刁奼的任務是祕密進⾏的,爲了調查商⼈的賬本,她只好跑到商⼈那⾥打⼯。她趁商⼈不在時去偷看賬本,可是她⽆法將賬本偷出來,每次偷看賬本時她都只能看某段時間內賬本上記錄的收⼊情況,並且她只能記住這段時間內的總收⼊。現在,刁奼總共偷看了m 次賬本,當然也就記住了m 段時間內的總收⼊,你的任務是根據記住的這些信息來判斷賬本是不是假的。
每個測試點內有T<100 組數據,每組都滿足n<100,m<1000 .

題解:

帶權並查集,在合併的時候維護一下權值就可以了。

/*
  ID:Agreement
  LANG:C++
*/
// Invincible
#include <bits/stdc++.h>
#define rep( i , l , r ) for( int i = (l) ; i <= (r) ; ++i )
#define per( i , r , l ) for( int i = (r) ; i >= (l) ; --i )
#define erep( i , u ) for( int i = head[(u)] ; ~i ; i = e[i].nxt )
using namespace std;
const int maxn = 100 + 5;
int f[maxn] , v[maxn] , flg; 
int Find( int x ){
    if( x == f[x] ) return x;
    int t = Find( f[x] );
    v[x] += v[f[x]];
    return f[x] = t;
}
void ins( int x , int y , int w ){
    int fx = Find( x ) , fy = Find( y );
    if( fx != fy ){
        f[fx] = fy;
        v[fx] = v[y] - v[x] - w;
    }else if( v[y] - v[x] != w ) flg = 1;
} 
int main(){
    int T = 0 , N = 0 , M = 0 , x , y , w ;
    scanf("%d" , &T);
    while( T-- ){
        flg = 0;
        scanf("%d %d" , &N , &M);
        memset( v , 0 , sizeof v );
        rep( i , 0 , N ) f[i] = i;
        rep( i , 1 , M ){
            scanf("%d %d %d" , &x , &y , &w);
            ins( x - 1 , y , w );
        }
        if( flg ) puts("false");
        else puts("true");
    } 
    return 0;
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章