版权声明:本文为DyingShu原创文章,转载请注明出处哦。 https://blog.csdn.net/DyingShu/article/details/82805306
题目一看就是差分约束系统。。。不知道为什么有人会想到最短路
我用了一种奇奇怪怪的做法:最短路。
以天数为点,以花费来建图
首先发现如果一个账本是正确无误的,则每条到该点的路径中,长度都应该是相等的。
所以只要判断到每个点的最长路和最短路是否相等就行了
于是看到数据范围,floyd过不了,直接一个多源SPFA23333
不管了反正过了.jpg 不过应该有更好的做法的
细节:因为题目给出条件时说的是从
月初到
月末的收支情况,所以看作是
月初到
月初的收入,就不存在自环了
#include<cstdio>
#include<cstring>
#include<queue>
#include<algorithm>
using namespace std;
typedef long long LL;
const int MAXN = 105;
const int MAXM = 1001;
const LL INF = 1e15;
int fir[MAXN], nxt[MAXM << 1], to[MAXM << 1], len[MAXM << 1], cnt;
LL Maxdis[MAXN][MAXN], Mindis[MAXN][MAXN];
LL dis[MAXN][MAXN];
int vis[MAXN];
inline int read(){
int k = 0, f = 1; char ch = getchar();
while(ch < '0' || ch > '9'){if(ch == '-') f = -1; ch = getchar();}
while(ch >= '0' && ch <= '9'){k = k*10 + ch - '0'; ch = getchar();}
return k * f;
}
inline void add_edge(int a, int b, int l){
len[cnt] = l;
to[cnt] = b;
nxt[cnt] = fir[a];
fir[a] = cnt++;
}
void SPFA1(int x){
queue<int> q; q.push(x);
memset(vis, 0, sizeof(vis)); vis[x] = true;
Maxdis[x][x] = 0;
int u;
while(!q.empty()){
u = q.front(); q.pop(); vis[u] = false;
for(int i = fir[u]; i != -1; i = nxt[i]){
int v = to[i];
if(Maxdis[x][v] < Maxdis[x][u] + len[i]){
Maxdis[x][v] = Maxdis[x][u] + len[i];
if(!vis[v]){
q.push(v);
vis[v] = true;
}
}
}
}
}
void SPFA2(int x){
queue<int> q; q.push(x);
memset(vis, 0, sizeof(vis)); vis[x] = true;
Mindis[x][x] = 0;
int u;
while(!q.empty()){
u = q.front(); q.pop(); vis[u] = false;
for(int i = fir[u]; i != -1; i = nxt[i]){
int v = to[i];
if(Mindis[x][v] > Mindis[x][u] + len[i]){
Mindis[x][v] = Mindis[x][u] + len[i];
if(!vis[v]){
q.push(v);
vis[v] = true;
}
}
}
}
}
int main(){
int T = read();
while(T--){
memset(fir, -1, sizeof(fir)); cnt = 0;
// memset(dis, false, sizeof(dis));
memset(dis, 0x3f, sizeof(dis));
memset(Maxdis, 0xcf, sizeof(Maxdis));
memset(Mindis, 0x3f, sizeof(Mindis));
int n = read() + 1, m = read();
// for(int i = 1; i <= n + 1; i++){
// dis[i][i] = true;
// Maxdis[i][i] = Mindis[i][i] = 0;
// }
bool Flag = false;
for(int i = 1; i <= m; i++){
int a = read(), b = read() + 1, l = read();
if(Mindis[a][b] < INF && Mindis[a][b] != l) Flag = true;
if(Mindis[a][b] >= INF){
add_edge(a, b, l);
}
// if(Mindis[a][b] < INF) if(Mindis[a][b] != l) Flag = true;
// if(Mindis[a][b] >= INF){
// Maxdis[a][b] = Mindis[a][b] = l;
// dis[a][b] = 1;
// }
}
if(Flag){
puts("false");
continue;
}
for(int i = 1; i <= n + 1; i++){
SPFA1(i);
SPFA2(i);
// printf("i = %d\n", i);
// for(int j = 1; j <= n + 1; j++){
// printf("%d : Max = %lld Min = %lld\n", j, Maxdis[i][j], Mindis[i][j]);
// }
for(int j = i + 1; j <= n + 1; j++){
if(Mindis[i][j] < INF){
if(Maxdis[i][j] != Mindis[i][j]){
Flag = true;
break;
}
}
}
if(Flag) break;
}
if(Flag){
puts("false");
}
else{
puts("true");
}
}
return 0;
}