bzoj1731 [Usaco2005 dec]Layout 排队布局
分析
我们发现这两类关系可以写成b-a<=L和b-a>=D两种形式,所以我们可以得到这两种的连边策略分别是a向b连一条权值为L的边和b向a连一条权值为-D的边。然后我们跑最短路即可。注意要单独判一下负环。
代码
#include<iostream>
#include<cstdio>
#include<cstring>
#include<string>
#include<algorithm>
#include<cctype>
#include<cmath>
#include<cstdlib>
#include<queue>
#include<ctime>
#include<vector>
#include<set>
#include<map>
#include<stack>
using namespace std;
const int inf = 0x3f3f3f3f;
vector<pair<int,int> >v[11000];
int d[11000];
int main(){
int n,m1,m2,i,j,k;
scanf("%d%d%d",&n,&m1,&m2);
for(i=1;i<=m1;i++){
int x,y,z;
scanf("%d%d%d",&x,&y,&z);
v[x].push_back(make_pair(y,z));
}
for(i=1;i<=m2;i++){
int x,y,z;
scanf("%d%d%d",&x,&y,&z);
v[y].push_back(make_pair(x,-z));
}
memset(d,0x3f,sizeof(d));
d[1]=0;
for(int _=1;_<=n;_++)
for(int x=1;x<=n;x++)
for(i=0;i<v[x].size();i++){
int y=v[x][i].first,z=v[x][i].second;
d[y]=min(d[y],d[x]+z);
}
for(int x=1;x<=n;x++)
for(i=0;i<v[x].size();i++){
int y=v[x][i].first,z=v[x][i].second;
if(d[y]>d[x]+z){
puts("-1");
return 0;
}
}
if(d[n]>=inf)puts("-2");
else cout<<d[n]<<endl;
return 0;
}