ZOJ 2770 Burn the Linked Camp 差分约束 ZOJ排名第一~

来源:互联网 发布:vscode搭建kotlin 编辑:程序博客网 时间:2024/05/19 13:27

http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemId=1770

题目大意:

陆逊为了火烧连营七百里,派出了间谍刺探敌情,得之刘备的军营以1~n编号一字排开,第i个大营最多能容纳Ci个士兵。而且通过观察刘备军队的动静,陆逊可以估计到从第i个大营到第j个大营至少有多少士兵。最后,陆逊必须估计出刘备最少有多少士兵,这样他才知道要派多少士兵去烧刘备的大营。为陆逊估计出刘备军队至少有多少士兵。然而,陆逊的估计可能不是很精确,如果不能很精确地估计出来,输出"Bad Estimations"

思路:

第一道差分约束题。。(卧槽,我又一个第一次没了!好像很口怕的样子)

不过ZOJ排名第一。。。。


设s[i]为前i个军营的总人数。

则有:

0<=s[i]-s[i-1]<=C[i];
s[ j ]-s[i-1]>=z(”陆逊可以估计到从第i个大营到第j个大营至少有多少士兵“)

然后建立图。

还有就是增加一个源点S,使它与其他所有顶点的边都为0,为什么?添加从虚点S到每个顶点的权为0的边.这是为了保证构造出来的图是连通的.由于虚点本身并不引入负圈,所以设置虚点以后最短路仍然存在,并且每个约束仍然满足.

#include<cstdio>#include<cstring>#include<queue>using namespace std;const int MAXN=1000+10;const int MAXM=10000+10;const int INF=-100000000;struct edge{int to;int val;int next;}e[MAXM];int head[MAXN],len,n,m,c,dis[MAXN];void add(int from,int to,int val){e[len].to=to;e[len].val=val;e[len].next=head[from];head[from]=len++;}bool spfa(){for(int i=0;i<=n;i++)dis[i]=INF;bool vis[MAXN]={0};int cnt[MAXN]={0};queue<int> q;dis[0]=0;vis[0]=true;cnt[0]=1;q.push(0);while(!q.empty()){int cur=q.front();q.pop();vis[cur]=false;for(int i=head[cur];i!=-1;i=e[i].next){int id=e[i].to;if(dis[cur] + e[i].val > dis[id]){dis[id]=dis[cur]+e[i].val;if(!vis[id]){cnt[id]++;if(cnt[cur] > n)return false;vis[id]=true;q.push(id);}}}}return true;}int main(){while(~scanf("%d%d",&n,&m)){len=0;memset(head,-1,sizeof(head));for(int i=1;i<=n;i++){scanf("%d",&c);add(i,i-1,-c);add(i-1,i,0);add(0,i,0);}for(int i=0;i<m;i++){int from,to,val;scanf("%d%d%d",&from,&to,&val);add( from-1,to,val);}if(spfa())printf("%d\n",dis[n]);elseputs("Bad Estimations");}return 0;}

一开始全部点入队列

#include<cstdio>#include<cstring>#include<queue>using namespace std;const int MAXN=1000+10;const int MAXM=10000+10;const int INF=-100000000;struct edge{int to;int val;int next;}e[MAXM];int head[MAXN],len,n,m,c,dis[MAXN];void add(int from,int to,int val){e[len].to=to;e[len].val=val;e[len].next=head[from];head[from]=len++;}bool spfa(){bool vis[MAXN];int cnt[MAXN];queue<int> q;for(int i=0;i<=n;i++){dis[i]=0;vis[i]=true;q.push(i);cnt[i]=1;}while(!q.empty()){int cur=q.front();q.pop();vis[cur]=false;for(int i=head[cur];i!=-1;i=e[i].next){int id=e[i].to;if(dis[cur] + e[i].val > dis[id]){dis[id]=dis[cur]+e[i].val;if(!vis[id]){cnt[id]++;if(cnt[cur] > n)return false;vis[id]=true;q.push(id);}}}}return true;}int main(){while(~scanf("%d%d",&n,&m)){len=0;memset(head,-1,sizeof(head));for(int i=1;i<=n;i++){scanf("%d",&c);add(i,i-1,-c);add(i-1,i,0);//add(0,i,0);}for(int i=0;i<m;i++){int from,to,val;scanf("%d%d%d",&from,&to,&val);add( from-1,to,val);}if(spfa())printf("%d\n",dis[n]);elseputs("Bad Estimations");}return 0;}


7 0
原创粉丝点击