zoj 2770(差分约束)

设a[i] 为第i个营的人数,s[i] = a[1] + a[2] + … + a[i], s[0] = 0

       则对于题目

       Ci 有: 0 <= s[i] – s[i-1] <= a[i]  -----(1)

       i, j, k有:a[i]+a[i+1]+...a[j]>= s[j] – s[i-1] >= k   -----(2)

       化为以下四个式子:

s[i]-s[i-1]<=a[i]  ------>addedge(i-1,i,a[i])

s[i-1]-s[i]<=0 --------->addedge(i,i-1,0)

s[j]-s[i-1]<=sum[j]-sum[i-1]----->addedge(i-1,j,sum[j]-sum[i-1])

s[i-1]-s[j]<=-k  ---->addedge(j,i-1,-k)

设答案为ans.则显然s[n]-s[0]>=ans  ---->s[0]-s[n]<=-ans;

相当于从n-->0的边权值为-ans。

故可以从n为源点求最短路.

 

另外:用vector来存邻接表貌似很方便。。

 

 1 // File Name: 2770.cpp
 2 // Author: Missa
 3 // Created Time: 2013/2/20 星期三 12:22:46
 4 
 5 #include<iostream>
 6 #include<cstdio>
 7 #include<cstring>
 8 #include<algorithm>
 9 #include<cmath>
10 #include<queue>
11 #include<stack>
12 #include<string>
13 #include<vector>
14 #include<cstdlib>
15 #include<map>
16 #include<set>
17 using namespace std;
18 #define CL(x,v) memset(x,v,sizeof(x));
19 const int inf = 0x3f3f3f3f;
20 const int maxm = 2e5+5;
21 const int maxn = 1005;
22 int n,m;
23 struct edge
24 {
25     int v;
26     int c;
27     edge(){}
28     edge(int v,int c):v(v),c(c){}
29 };
30 vector<edge>e[maxn];
31 int a[maxn],sum[maxn],dis[maxn],cnt[maxn];
32 void addedge(int u,int v,int c)
33 {
34     e[u].push_back(edge(v,c));
35 }
36 bool relax(int u,int v,int c)
37 {
38     if(dis[v]>dis[u]+c)
39     {
40         dis[v]=dis[u]+c;
41         return true;
42     }
43     return false;
44 }
45 bool spfa(int src)
46 {
47     bool vis[maxn];CL(vis,0);
48     CL(dis,0x3f);
49     dis[src]=0;vis[src]=1;
50     queue<int>q;q.push(src);
51     while(!q.empty())
52     {
53         int pre=q.front();q.pop();
54         vis[pre]=0;
55         for(int i=0;i<e[pre].size();i++)
56         {
57             if(relax(pre,e[pre][i].v,e[pre][i].c) && !vis[e[pre][i].v])
58             {
59                 if((++cnt[e[pre][i].v]) > n) return false;
60                 q.push(e[pre][i].v);
61                 vis[e[pre][i].v]=1;
62             }
63         }
64     }
65     return true;
66 }
67 int main()
68 {
69     while(~scanf("%d%d",&n,&m))
70     {
71         CL(a,0);
72         CL(sum,0);
73         CL(cnt,0);
74         CL(e,0);
75         int u,v,c;
76         for(int i=1;i<=n;i++)
77         {
78             scanf("%d",&a[i]);
79             sum[i]=sum[i-1]+a[i];
80         }
81         for(int i=1;i<=m;i++)
82         {
83             scanf("%d%d%d",&u,&v,&c);
84             addedge(v,u-1,-c);
85             addedge(u-1,v,sum[v]-sum[u-1]);
86         }
87         for(int i=1;i<=n;i++)
88         {
89             addedge(i,i-1,0);
90             addedge(i-1,i,a[i]);
91         }
92         if(!spfa(n)) puts("Bad Estimations");
93         else
94             printf("%d\n",dis[n]-dis[0]);
95     }
96     return 0;
97 }

 

 

 

posted @ 2013-02-20 15:03  Missa  阅读(404)  评论(0编辑  收藏  举报