【poj3169】【差分约束+spfa】
题目链接http://poj.org/problem?id=3169
题目大意:
一些牛按序号排成一条直线。
有两种要求,A和B距离不得超过X,还有一种是C和D距离不得少于Y,问可能的最大距离。如果没有输出-1,如果可以随便排输出-2,否则输出最大的距离。
首先关于差分约束:https://blog.csdn.net/consciousman/article/details/53812818
了解了差分约束之后就知道该题典型的差分约束+spfa即可。
1 #include<iostream> 2 #include<cstdio> 3 #include<cstring> 4 using namespace std; 5 const int INF=0x3f3f3f3f; 6 struct pot{ 7 int to; 8 int next; 9 int len; 10 }edge[20005]; 11 int next[1005]; 12 int d[1005]; 13 int cnt[1005]; 14 bool vis[1005]; 15 int que[1005]; 16 int tot=0,front=1,back=0; 17 int n,m,q; 18 void add(int x,int y,int t) 19 { 20 edge[tot].to=y; 21 edge[tot].len=t; 22 edge[tot].next=next[x]; 23 next[x]=tot++; 24 } 25 bool spfa() 26 { 27 d[1]=0; 28 vis[1]=true; 29 que[front++]=1; 30 cnt[1]++; 31 while(front!=back) 32 { 33 back++; 34 if(back>=1005)back=0; 35 vis[que[back]]=false; 36 for(int i = next[que[back]];i!=-1;i=edge[i].next) 37 { 38 if(d[edge[i].to]>d[que[back]]+edge[i].len) 39 { 40 d[edge[i].to]=d[que[back]]+edge[i].len; 41 if(!vis[edge[i].to]) 42 { 43 que[front++]=edge[i].to; 44 if(front>=1005)front=0; 45 vis[edge[i].to]=true; 46 cnt[edge[i].to]++; 47 if(cnt[edge[i].to]>n)return false; 48 } 49 } 50 } 51 } 52 return true; 53 } 54 int main() 55 { 56 scanf("%d%d%d",&n,&m,&q); 57 for(int i = 1 ;i <= n ; i++) 58 { 59 next[i]=-1; 60 d[i]=INF; 61 vis[i]=false; 62 cnt[i]=0; 63 } 64 for(int i = 0 ; i < m ; i++) 65 { 66 int a,b,c; 67 scanf("%d%d%d",&a,&b,&c); 68 if(a>b) 69 { 70 int t=a; 71 a=b; 72 b=t; 73 } 74 add(a,b,c); 75 } 76 for(int i = 0 ; i < q ; i++) 77 { 78 int a,b,c; 79 scanf("%d%d%d",&a,&b,&c); 80 if(b>a) 81 { 82 int t=a; 83 a=b; 84 b=t; 85 } 86 add(a,b,-c); 87 } 88 if(!spfa())printf("-1\n"); 89 else if(d[n]==INF)printf("-2\n"); 90 else printf("%d\n",d[n]); 91 return 0; 92 }