您的位置:首页 > 其它

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

2014-01-26 00:30 429 查看
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
);
		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
);
		else
			puts("Bad Estimations");
	}

	return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: