bzoj1202: [HNOI2005]狡猾的商人(差分约束)
1202: [HNOI2005]狡猾的商人
题目:传送门
题解:
据说是带权并查集!蒟蒻不会啊!!!
可是听说lxj大佬用差分约束A了,于是开始一通乱搞。
设s[i]为前i个月的总收益,那么很容易就可以推出约束条件了啊:
s[x-1]>=s[y]-c s[y]>=s[x-1]+c
然后就可以去跑最长路了
吐槽:
lxj大佬推出来的条件竟然是两个小于等于号:s[x-1]<=s[y]-c s[y]<=s[x-1]+c
然后跑最短路也A了,表示很玄学qwq
代码:
1 #include<cstdio> 2 #include<cstring> 3 #include<cstdlib> 4 #include<cmath> 5 #include<algorithm> 6 using namespace std; 7 int T; 8 struct tj 9 { 10 int x,y,d; 11 }b[2100]; 12 struct node 13 { 14 int x,y,d,next; 15 }a[2100];int len,last[2100]; 16 int s[2100],d[2100]; 17 void ins(int x,int y,int d) 18 { 19 len++;a[len].x=x;a[len].y=y;a[len].d=d; 20 a[len].next=last[x];last[x]=len; 21 } 22 bool v[2100];int ru[2100],list[2100]; 23 int main() 24 { 25 scanf("%d",&T); 26 while(T--) 27 { 28 memset(s,0,sizeof(0)); 29 int n,m;scanf("%d%d",&n,&m); 30 len=0;memset(last,0,sizeof(last)); 31 for(int i=1;i<=m;i++) 32 { 33 int x,y,d; 34 scanf("%d%d%d",&x,&y,&d); 35 ins(y,x-1,-d);ins(x-1,y,d); 36 } 37 /* 38 s[x-1]>=s[y]-c s[y]>=s[x-1]+c 39 */ 40 for(int i=1;i<=n;i++)d[i]=-999999999; 41 int head=0;for(int i=n;i>=0;i--)list[++head]=i; 42 memset(v,0,sizeof(v));memset(ru,0,sizeof(ru)); 43 bool bk=true; 44 while(head!=0) 45 { 46 int x=list[head--];v[x]=true; 47 for(int k=last[x];k;k=a[k].next) 48 { 49 int y=a[k].y; 50 if(d[y]<d[x]+a[k].d) 51 { 52 d[y]=d[x]+a[k].d; 53 ru[y]++;if(ru[y]==n+1){bk=false;break;} 54 if(v[y]==true)v[y]=false,list[++head]=y; 55 } 56 } 57 if(bk==false)break; 58 } 59 if(bk==false)printf("false\n"); 60 else printf("true\n"); 61 } 62 return 0; 63 }