标签:
题意:一个农夫有n头牛,他希望将这些牛按照编号 1~n排成一条直线,允许有几头牛站在同一点,但是必须按照顺序,有一些牛关系比较好,希望站的距离不超过某个值,而有一些牛关系不太好,所以希望站的距离大于等于某个值,问1号牛和n号牛之间的最远距离是多少。
差分约束的裸题,对于 d[v] - d[u] ≤ w 建立权值为 w 的单向边 e(u,v),对于 d[v] - d[u] ≥ w 建立权值为 -w 的单向边 e(v,u),然后再根据牛必须按顺序排列建立权值为 0 的边 e(i+1,i),然后最短路就行了。
1 #include<stdio.h>
2 #include<string.h>
3 #include<queue>
4 using namespace std;
5 const int maxn=1005;
6 const int maxm=30005;
7 const int INF=0x3f3f3f3f;
8
9 int head[maxn],nxt[maxm],point[maxm],val[maxm],size;
10 int vis[maxn],dis[maxn],n,num[maxn];
11
12 void add(int a,int b,int v){
13 val[size]=v;
14 point[size]=b;
15 nxt[size]=head[a];
16 head[a]=size++;
17 }
18
19 int spfa(){
20 memset(vis,0,sizeof(vis));
21 memset(dis,0x3f,sizeof(dis));
22 memset(num,0,sizeof(num));
23 queue<int>q;
24 vis[1]=1;
25 dis[1]=0;
26 q.push(1);
27 while(!q.empty()){
28 int u=q.front();
29 q.pop();
30 vis[u]=0;
31 for(int i=head[u];~i;i=nxt[i]){
32 int j=point[i];
33 if(dis[j]>dis[u]+val[i]){
34 dis[j]=dis[u]+val[i];
35 if(!vis[j]){
36 q.push(j);
37 vis[j]=1;
38 if(++num[j]>n)return 1;
39 }
40 }
41 }
42 }
43 return 0;
44 }
45
46 int main(){
47 int ml,md;
48 scanf("%d%d%d",&n,&ml,&md);
49 size=0;
50 memset(head,-1,sizeof(head));
51 while(ml--){
52 int a,b,v;
53 scanf("%d%d%d",&a,&b,&v);
54 add(a,b,v);
55 }
56 while(md--){
57 int a,b,v;
58 scanf("%d%d%d",&a,&b,&v);
59 add(b,a,-v);
60 }
61 for(int i=1;i<n;++i)add(i+1,i,0);
62 if(spfa())printf("-1\n");
63 else if(dis[n]==INF)printf("-2\n");
64 else printf("%d\n",dis[n]);
65 return 0;
66 }
标签:
原文地址:http://www.cnblogs.com/cenariusxz/p/4787540.html