1. 程式人生 > >[BZOJ1202] [NZOI2005]狡猾的商人

[BZOJ1202] [NZOI2005]狡猾的商人

ret 多少 push 個數 out style get include turn

Description

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

Input

第一行為一個正整數w,其中w < 100,表示有w組數據,即w個賬本,需要你判斷。每組數據的第一行為兩個正整數n和m,其中n < 100,m < 1000,分別表示對應的賬本記錄了多少個月的收入情況以及偷看了多少次賬本。接下來的m行表示刁姹偷看m次賬本後記住的m條信息,每條信息占一行,有三個整數s,t和v,表示從第s個月到第t個月(包含第t個月)的總收入為v,這裏假設s總是小於等於t。

Output

包含w行,每行是true或false,其中第i行為true當且僅當第i組數據,即第i個賬本不是假的;第i行為false當且僅當第i組數據,即第i個賬本是假的。

Sample Input

2
3 3
1 2 10
1 3 -5
3 3 -15
5 3
1 5 100
3 5 50
1 2 51

Sample Output

true
false

比較裸的差分約束。 就是按照題目要求連邊,判斷是否有負環。 一個數組沒有清零Wa了好久。
#include <iostream>
#include <cstdio>
#include <queue>
#include <cstring>
#include <algorithm>
using namespace std;
#define reg register
inline int read() {
int res=0;char ch=getchar();bool fu=0;
while(!isdigit(ch)) {if(ch==‘-‘)fu=1;ch=getchar();}
while(isdigit(ch))res=(res<<3)+(res<<1)+(ch^48),ch=getchar();
return fu?-res:res;
}
#define N 105
#define M 6005
int T;
int n, m;
struct edge {
int nxt, to, val;
}ed[M];
int head[M], cnt;

inline void add(int x, int y, int z) {
ed[++cnt] = (edge){head[x], y, z};
head[x] = cnt;
}
int tim[M];
int S;
int dis[M];
bool ex[M];
inline bool spfa()
{
memset(dis, 0x3f, sizeof dis);
dis[S] = 0;
queue <int> q;
q.push(S);
while(!q.empty())
{
int x = q.front();q.pop();
tim[x]++;
if (tim[x] >= n) return 0;
ex[x] = 0;
for (reg int i = head[x] ; i ; i = ed[i].nxt)
{
int to = ed[i].to;
if (dis[to] > dis[x] + ed[i].val)
{
dis[to] = dis[x] + ed[i].val;
if (!ex[to]) ex[to] = 1, q.push(to);
}
}
}
return 1;
}
int main()
{
T = read();
while(T--)
{
memset(head, 0, sizeof head);
memset(tim, 0, sizeof tim);
memset(ex, 0, sizeof ex);
cnt = 0;
n = read(), m = read();
S = n + 1;
for (reg int i = 0 ; i <= n ; i ++)
add(S, i, 0);
for (reg int i = 1 ; i <= m ; i ++)
{
int x = read(), y = read(), z = read();
add(x - 1, y, z), add(y, x - 1, -z);
}
if (spfa()) puts("true");
else puts("false");
}
return 0;
}

[BZOJ1202] [NZOI2005]狡猾的商人