[Bzoj1731]排队布局
洛谷上的翻译是真的哲学♂♂♂
个人认为这题充其量也就是个蓝(nan)题,首先处理-1的情况,-1的情况是不等式组无解,按照差分约束的规则,无解说明出现了负环,先跑一遍以0为源点的SPFA判断有无负环即可。再来处理-2的情况,结果为-2就说明1号和n号节点不存在直接的或间接的约束关系,所以我们跑一遍以1为源点SPFA看1到n连不连通即可。最后如果答案不为-1和-2,那么dist[n]就是答案啦。~~~♂♂♂♂♂♂♂♂♂
参考程序如下:
1 #include<iostream> 2 #include<cstring> 3 #include<queue> 4 #define inf 336860180 5 using namespace std; 6 int n,ml,md,v[50005],w[50005],head[50005],nxt[50005],cnt,ring[100001],dist[100001],a,b,d; 7 bool vis[100001]; 8 void add(int a,int b,int c) 9 { 10 v[++cnt]=b; 11 w[cnt]=c; 12 nxt[cnt]=head[a]; 13 head[a]=cnt; 14 } 15 bool spfa(int s) 16 { 17 memset(dist,20,sizeof(dist)); 18 memset(ring,0,sizeof(ring)); 19 dist[s]=0; 20 queue<int>q; 21 q.push(s); 22 vis[s]=1; 23 while(!q.empty()) 24 { 25 int c=q.front(); 26 q.pop(); 27 vis[c]=0; 28 ring[c]++; 29 if(ring[c]==n)return 1; 30 for(int i=head[c];i;i=nxt[i]) 31 { 32 int y=v[i]; 33 if(dist[y]>dist[c]+w[i]) 34 { 35 dist[y]=dist[c]+w[i]; 36 if(!vis[y]) 37 { 38 q.push(y); 39 vis[y]=1; 40 } 41 } 42 } 43 } 44 return 0; 45 } 46 int main() 47 { 48 cin>>n>>ml>>md; 49 for(int i=1;i<=ml;i++) 50 { 51 cin>>a>>b>>d; 52 add(a,b,d); 53 } 54 for(int i=1;i<=md;i++) 55 { 56 cin>>a>>b>>d; 57 add(b,a,-d); 58 } 59 for(int i=1;i<=n;i++)add(0,i,0); 60 if(spfa(0)) 61 { 62 cout<<"-1"; 63 return 0; 64 } 65 spfa(1); 66 if(dist[n]==inf) 67 { 68 cout<<"-2"; 69 return 0; 70 } 71 cout<<dist[n]<<endl; 72 return 0; 73 }