标签:
题意:有n头牛,编号为1到n,对于关系好的ml头牛,al和bl之间的距离不大于dl,关系差的md头牛,ad和bd之间的距离不大于dd,求第1头牛和第n头牛之间的距离
分析:这是一道差分约束系统的题目,先来看一下查分约束系统的资料
http://www.cnblogs.com/void/archive/2011/08/26/2153928.html
于是上述问题可以转换成最短路问题来求解,设d[i]为第1个顶点到第i个顶点的最短距离,d[al[i]]+dl[i]>=d[bl[i]],于是d[bl[i]]-d[al[i]]<=dl[i],同理可得d[ad[i]]-d[bd[i]]<=-dd[i],然后建立最短路来求解即可,因为存在负圈,所以用Bellman-Ford来求最短路
1 #include <iostream> 2 #include <cstdio> 3 #include <cstring> 4 #include <string> 5 #include <vector> 6 #include <algorithm> 7 #include <set> 8 #include <map> 9 #include <bitset> 10 #include <cmath> 11 #include <queue> 12 #include <stack> 13 using namespace std; 14 const int maxn=10010; 15 const int INF=1<<30; 16 int al[maxn],bl[maxn],dl[maxn]; //互相之间喜欢的牛 17 int ad[maxn],bd[maxn],dd[maxn]; //互相之间讨厌的牛 18 int n,ml,md; 19 int d[maxn]; //最短路 20 21 void solve() 22 { 23 fill(d,d+n+1,INF); 24 d[1]=0; 25 for(int k=0;k<n;k++) 26 { 27 for(int i=1;i<n;i++) 28 { 29 if(d[i+1]<INF) 30 d[i]=min(d[i+1],d[i]); 31 } 32 for(int i=0;i<ml;i++) 33 { 34 if(d[al[i]]<INF) 35 d[bl[i]]=min(d[bl[i]],d[al[i]]+dl[i]); 36 } 37 for(int i=0;i<md;i++) 38 { 39 if(d[bd[i]]<INF) 40 d[ad[i]]=min(d[bd[i]]-dd[i],d[ad[i]]); 41 } 42 } 43 } 44 45 int main() 46 { 47 while(cin>>n>>ml>>md) 48 { 49 for(int i=0;i<ml;i++){ 50 scanf("%d%d%d",&al[i],&bl[i],&dl[i]); 51 } 52 for(int i=0;i<md;i++){ 53 scanf("%d%d%d",&ad[i],&bd[i],&dd[i]); 54 } 55 solve(); 56 int res=d[n]; 57 if(d[1]<0){ 58 cout<<"-1"<<endl; 59 }else if(res==INF){ 60 cout<<"-2"<<endl; 61 }else 62 cout<<res<<endl; 63 } 64 return 0; 65 }
标签:
原文地址:http://www.cnblogs.com/wolf940509/p/5675245.html