【差分约束系统/SPFA】POJ3169-Layout

【题目大意】

n头牛从小到大排,它们之间某些距离不能大于一个值,某些距离不能小于一个值,求第一头牛和第N头牛之间距离的最大值。

【思路】

由题意可以得到以下不等式d[AL]+DL≥d[BL];d[BD]+(-DD)≥d[AD];d[i+1]+0≥d[i],显然是差分约束系统。即构造从AL到BL权值为DL的边,从BD到AD构造权值为-DD的负边,从i+1到i构造权值为0的边。最后求最短路径。安利一个证明(点我)。

对于差分约束系统要注意的是,如果要求最大距离,用最短路径;求最小距离,用最长路径,要根据实际情况判断。

 1 #include<iostream>
 2 #include<cstdio>
 3 #include<cstring>
 4 #include<queue>
 5 using namespace std;
 6 const int MAXN=10000+5;
 7 struct Rec
 8 {
 9     int ori,des,len;
10 };
11 int n,ml,md;
12 int first[MAXN/10],next[MAXN*2+1000];
13 Rec edge[MAXN*2+1000];
14 int vis[MAXN/10],dis[MAXN/10],appear[MAXN/10];
15 
16 void init()
17 {
18     memset(first,-1,sizeof(first));
19     scanf("%d%d%d",&n,&ml,&md);
20     int j=-1;
21     for (int i=0;i<ml;i++)
22     {
23         j++;
24         scanf("%d%d%d",&edge[j].ori,&edge[j].des,&edge[j].len);
25         edge[j].ori--;edge[j].des--;
26         next[j]=first[edge[j].ori];
27         first[edge[j].ori]=j;
28     }
29     for (int i=0;i<md;i++)
30     {
31         j++;
32         scanf("%d%d%d",&edge[j].des,&edge[j].ori,&edge[j].len);
33         edge[j].ori--;edge[j].des--;
34         edge[j].len=0-edge[j].len;
35         next[j]=first[edge[j].ori];
36         first[edge[j].ori]=j;
37     }
38     for (int i=1;i<n;i++)
39     {
40         j++;
41         edge[j].ori=i;edge[j].des=i-1;edge[j].len=0;
42         next[j]=first[edge[j].ori];
43         first[edge[j].ori]=j;
44     }
45 }
46 
47 void SPFA()
48 {
49     queue<int> que;
50     memset(vis,0,sizeof(vis));
51     memset(appear,0,sizeof(appear));
52     for (int i=1;i<n;i++) dis[i]=0x7fffffff;
53     dis[0]=0;
54     que.push(0);
55     vis[0]=1;
56     appear[0]++;
57     
58     while (!que.empty())
59     {
60         int head=que.front();
61         int k=first[head];
62         while (k!=-1)
63         {
64             Rec e=edge[k];
65             if (dis[e.des]>dis[e.ori]+e.len)
66             {
67                 dis[e.des]=dis[e.ori]+e.len;
68                 if (!vis[e.des])
69                 {
70                     appear[e.des]++;
71                     if (appear[e.des]>n)
72                     {
73                         cout<<-1<<endl;
74                         return;
75                     }
76                     que.push(e.des);
77                     vis[e.des]=1;
78                 }
79             }
80             k=next[k];
81         }
82         vis[head]=0;
83         que.pop();
84     }
85     if (dis[n-1]==0x7fffffff) cout<<-2<<endl; else cout<<dis[n-1]<<endl;
86 }
87 
88 int main()
89 {
90     init();
91     SPFA();
92     system("pause");
93     return 0; 
94 } 

 

posted @ 2015-08-06 15:42  iiyiyi  阅读(321)  评论(0编辑  收藏  举报