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]); else puts("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]); else puts("Bad Estimations"); } return 0; }