码迷,mamicode.com
首页 > 其他好文 > 详细

ZOJ2770 Burn the Linked Camp(差分约束系统)

时间:2016-01-03 22:20:59      阅读:197      评论:0      收藏:0      [点我收藏+]

标签:

区间和一定要联系到前缀和。

  1. 这题,把前缀和看作点,从s0到sn;
  2. 对于每一个营地i的容量capi,有这么个关系si-si-1<=capi
  3. 对于每一个区间的评估i,j,k,有sj-si-1>=k,即si-1-sj<=k;
  4. 接下来就是连边了,对于v<=u+w由u向v连权w的边,超级源向n+1个点连权0的边。
  5. 最后跑SPFA,如果出现负环则无解;而有解的话,所求答案就在d[sn]里,不过因为题目的前缀和是非负整数且要求的最少,所以就要让d中所有数都同时加上合适的数得到另一个真正所求的解。
 1 #include<cstdio>
 2 #include<cstring>
 3 #include<queue>
 4 #include<algorithm>
 5 using namespace std;
 6 #define INF (1<<30)
 7 #define MAXN 1111
 8 #define MAXM 22222 
 9 
10 struct Edge{
11     int v,cost,next;
12 }edge[MAXM];
13 int head[MAXN],NE;
14 void addEdge(int u,int v,int cost){
15     edge[NE].v=v; edge[NE].cost=cost; edge[NE].next=head[u];
16     head[u]=NE++;
17 }
18 
19 int n,m,d[MAXN],cnt[MAXN];
20 bool vis[MAXN];
21 bool SPFA(){
22     for(int i=0; i<=n; ++i){
23         vis[i]=0; cnt[i]=0; d[i]=INF;
24     }
25     vis[n+1]=1; cnt[n+1]=1; d[n+1]=0;
26     queue<int> que;
27     que.push(n+1);
28     while(!que.empty()){
29         int u=que.front(); que.pop();
30         if(cnt[u]>n+1) return 0;
31         for(int i=head[u]; i!=-1; i=edge[i].next){
32             int v=edge[i].v;
33             if(d[v]>d[u]+edge[i].cost){
34                 d[v]=d[u]+edge[i].cost;
35                 if(!vis[v]){
36                     vis[v]=1;
37                     ++cnt[v];
38                     que.push(v);
39                 }
40             }
41         }
42         vis[u]=0;
43     }
44     return 1;
45 }
46 int main(){
47     int a,b,c,cap[MAXN];
48     while(~scanf("%d%d",&n,&m)){
49         for(int i=1; i<=n; ++i) scanf("%d",cap+i);
50 
51         memset(head,-1,sizeof(head));
52         NE=0;
53         for(int i=1; i<=n; ++i) addEdge(i-1,i,cap[i]);
54         for(int i=0; i<=n; ++i) addEdge(n+1,i,0);
55         while(m--){
56             scanf("%d%d%d",&a,&b,&c);
57             addEdge(b,a-1,-c);
58         }
59         if(SPFA()){
60             int tmp=INF;
61             for(int i=0; i<=n; ++i) tmp=min(tmp,d[i]);
62             if(tmp<0) d[n]-=tmp;
63             printf("%d\n",d[n]);
64         }else puts("Bad Estimations");
65     }
66     return 0;
67 } 

 

ZOJ2770 Burn the Linked Camp(差分约束系统)

标签:

原文地址:http://www.cnblogs.com/WABoss/p/5097194.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!