[ZOJ2770 Burn the Linked Camp]

[关键字]:图论 差分约束系统

[题目大意]:给出n个军营,每个军营最多有ci个士兵,且[ai,bi]之间至少有ki个士兵,问最少有多少士兵。

//========================================================================================================

[分析]:明显的差分约束系统的题目,网上关于这类题目的总结非常多但是又非常乱各执一词,建议每个人就认准一种讲法仔细研究实践,我推荐这篇博客:http://imlazy.ycool.com/post.1702305.html,讲的非常清楚。看完之后就可以解决这道题了,大概意思就是求最大值就把不等式化成x-y<=z的形式连接<y,x>,然后求最小路,而求最小值就是把不等式化成x-y>=z的形式连接<y,x>,然后求最大路。因为不等式要么无解要么有无数解,如果我们要求最后的最小值大于0可以在加一对不等式:x-s>=0,因为求是必定有初始化d[s]=0所以上式可以保证求出来一组大于0的解。

[代码]:

View Code
#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<algorithm>
using namespace std;

const int MAXN=1100;

struct node
{
int y,d,x;
}e[MAXN*20];
int d[MAXN];
int n,m,tot;

void Add(int x,int y,int d)
{
tot++;
e[tot].x=x;
e[tot].y=y;
e[tot].d=d;
}

int Bellman()
{
memset(d,200,sizeof(d));
d[0]=0;
bool f;
for (int i=1;i<=n;++i)
{
f=1;
for (int j=1;j<=tot;++j)
if (d[e[j].y]<d[e[j].x]+e[j].d)
{
d[e[j].y]=d[e[j].x]+e[j].d;
f=0;
}
if (f) break;
}
for (int i=1;i<=tot;++i)
if (d[e[i].y]<d[e[i].x]+e[i].d) return -1;
return d[n];
}

int main()
{
freopen("in.txt","r",stdin);
freopen("out.txt","w",stdout);
while (scanf("%d%d",&n,&m)!=EOF)
{
int x,y,z;
tot=0;
for (int i=1;i<=n;++i)
{
scanf("%d",&x);
Add(i-1,i,0);
Add(i,i-1,-x);
Add(0,i,0);
}
for (int i=1;i<=m;++i)
{
scanf("%d%d%d",&x,&y,&z);
Add(x-1,y,z);
}
int ans=Bellman();
if (ans==-1)
printf("Bad Estimations\n");
else
printf("%d\n",ans);
}
return 0;
}


 

你可能感兴趣的:(link)