BZOJ 1202: [HNOI2005]狡猾的商人【並查集】【路徑迭代】

Description

刁奼接到一個任務,爲稅務部門調查一位商人的賬本,看看賬本是不是僞造的。賬本上記錄了n個月以來的收入情況,其中第i 個月的收入額爲Ai(i=1,2,3…n-1,n), 。當 Ai大於0時表示這個月盈利Ai 元,當 Ai小於0時表示這個月虧損Ai 元。所謂一段時間內的總收入,就是這段時間內每個月的收入額的總和。 刁奼的任務是祕密進行的,爲了調查商人的賬本,她只好跑到商人那裏打工。她趁商人不在時去偷看賬本,可是她無法將賬本偷出來,每次偷看賬本時她都只能看某段時間內賬本上記錄的收入情況,並且她只能記住這段時間內的總收入。 現在,刁奼總共偷看了m次賬本,當然也就記住了m段時間內的總收入,你的任務是根據記住的這些信息來判斷賬本是不是假的。

題解

聯賽前日常水。。。

並查集路徑迭代的裸題。

代碼

#include<cstdio>
#include<cstring>
#include<algorithm>
#define maxn 106
using namespace std;
inline char nc(){
    static char buf[100000],*i=buf,*j=buf;
    return i==j&&(j=(i=buf)+fread(buf,1,100000,stdin),i==j)?EOF:*i++;
}
inline int _read(){
    char ch=nc();int sum=0,p=1;
    while(ch!='-'&&!(ch>='0'&&ch<='9'))ch=nc();
    if(ch=='-')p=-1,ch=nc();
    while(ch>='0'&&ch<='9')sum=sum*10+ch-48,ch=nc();
    return sum*p;
}
int T,n,m,fa[maxn],dis[maxn];
int get(int x){
    if(fa[x]==x)return x;
    int y=fa[x];
    fa[x]=get(fa[x]);
    dis[x]+=dis[y];
    return fa[x];
}
bool merge(int x,int y,int z){
    int fx=get(x),fy=get(y);
    if(fx==fy)return dis[y]-dis[x]==z;
    if(fx<fy)fa[fy]=fx,dis[fy]=dis[x]+z-dis[y];
        else fa[fx]=fy,dis[fx]=dis[y]-z-dis[x];
    return 1;
}
int main(){
    freopen("businessman.in","r",stdin);
    freopen("businessman.out","w",stdout);
    T=_read();
    while(T--){
        n=_read();m=_read();bool ans=1;
        for(int i=1;i<=n+1;i++)fa[i]=i,dis[i]=0;
        for(int i=1;i<=m;i++){
            int x=_read(),y=_read(),z=_read();
            if(!merge(x,y+1,z))ans=0;
        }
        if(ans)printf("true\n");
          else printf("false\n");
    }
    return 0;
}
發佈了143 篇原創文章 · 獲贊 18 · 訪問量 3萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章