1. 程式人生 > >bzoj1202: [HNOI2005]狡猾的商人(差分約束)

bzoj1202: [HNOI2005]狡猾的商人(差分約束)

urn scan space 等於 -a OS 吐槽 set blank

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 }

bzoj1202: [HNOI2005]狡猾的商人(差分約束)