1202: [HNOI2005]狡猾的商人
Time Limit: 10 Sec Memory Limit: 162 MBSubmit: 1339 Solved: 636
[Submit][Status]
Description
Input
Output
Sample Input
3 3
1 2 10
1 3 -5
3 3 -15
5 3
1 5 100
3 5 50
1 2 51
Sample Output
false
【题解】我们可以这样想,账本能够判定为假的条件就是,有三段的和,并且最长段可以由另外两个拼起来,满足sum[3]!=sum[2]+sum[1];所以我用了一个数组f [ i ][ j ],记录i 到 j 的和为多少。然后考虑衔接,我们先将所有段按s 为第一关键字,t 为第二关键字从小到大排序,然后枚举 j, if(f[ j ][a[i].s-1]!=初值) 存在可以衔接的对象,在判断 if(f [ i ][ a[i].t ]==初值)则直接赋值,否则判断是否相等,不等则说明是假的。
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
struct node{int s,t,sum;}a[1000];
int f[100][100];
inline bool cmp(node x,node y)
{
if(x.s<y.s)return 1;
else if(x.s>y.s)return 0;
else return x.t<y.t;
}
int main()
{
int w,inf,n,m;scanf("%d",&w);
while(w--){
memset(f,0x7f,sizeof(f));
inf=f[1][1];
scanf("%d%d",&n,&m);
for(int i=1;i<=m;i++)scanf("%d%d%d",&a[i].s,&a[i].t,&a[i].sum);
sort(a+1,a+1+m,cmp);
bool key=0;
for(int i=1;i<=m;i++)
{
if(f[a[i].s][a[i].t]==inf)f[a[i].s][a[i].t]=a[i].sum;
else if(f[a[i].s][a[i].t]!=a[i].sum){key=1;break;}
for(int j=1;j<=a[i].s-1;j++)
if(f[j][a[i].s-1]!=inf)
if(f[j][a[i].t]==inf)f[j][a[i].t]=f[j][a[i].s-1]+a[i].sum;
else if(f[j][a[i].t]!=f[j][a[i].s-1]+a[i].sum)key=1;
if(key)break;
}
if(key)printf("false\n");
else printf("true\n");
}
return 0;
}