您的位置:首页 > 其它

差分约束小结 pku3169 1275 1716 3159 1364

2011-07-11 11:47 323 查看
差分约束:给定满足一些类似d[i]-d[j]<=w关系,求是否可能存在,最大,最小d是多少
分析:因为满足那种类型的等式,与最短路的等式是一样的,所以可以用最短路的思想解。关系全部转化为一种,要与最短路算法里面判断关系的符合互补(如关系全部化为<=,那么最短路判断时符号就应为>)。因为存在负权回路,所以要知道至少一种含负权的最短路算法,Bellman-ford,SPFA。。。强烈推荐SPFA。注意图是否连通。
pku3169给出羊的数目,i+1号羊不能站在i号羊的前面,某两只羊有最远距离或最近距离,求1至N的最远距离。
分析:首先把图构好,因为要求最远距离,所以所有初值赋为无穷大,需要变小时再变小。把所有关系都写成<=的形式,直接SPFA即可。。。最后返回值时判断一下,是否有负权环,是否N还是初值。。。
pku1275某商店二十四小时运营,每个小时都有最少在店人数,现在招人,每个应聘者都有上班起始时间,无论何时上班,连续上八个小时就下班。问最少招多少人?
分析:我们如果把招的每个小时开始上班人数存入x[i]中,s[i]表示前面总共招的人。那么针对每个小时最少在店人数r[i]有s[i]-s[i-8]>=r[i],当然注意每天循环。对于招的人数0<=s[i]-s[i-1]<=那时应聘总人数num[i]。可以把所有不等式都化成<=形式,好直接套用最短路模板
pku1716给出一些线段的两端点坐标,问使得每条线段最少含两个点的最少点的集合
分析:我们把前面点的数目和记为sum[i],对于某条线段[a,b]来说,有sum[b]-sum[a-1]>=2。。。注意0<=sum[i+1]-sum[i]<=1
pku3159 N个孩子分糖,给出一些关系(a,b,c)表示num[b]-num[a]<=c。。。问最大的差值是多少?
分析:关系就是最短路径的关系,不用变化。。。但此题要注意是否连通,因为题目说了大家都会跟某个人比,所以是连通的
pku1364 给定一些集合中子序列的和满足的关系(也就是类似sum[i]-sum[j]>k的关系),问是否可能。
分析:它给出的关系有>,<,我们通过+1,-1或者移项统一把它弄成<=,然后在SPFA里如果碰到大于的就更新。。。注意构的图可能不连通,所以开始所有结点都应入队
#include<iostream>
#include<vector>
using namespace std;

struct point
{
int v,w;
}qq;
vector<point> p[110];
int n,d[110];//d[i]表示从a[0]至a[i]的和

bool SPFA()
{
int q[110],times[110],head=0,tail=0,i,k;
bool inq[110];

//	memset(d,0,sizeof(d));//一般这里赋初值无穷大,但这里只判断,所以不介意
for(i=0;i<=n;i++)
d[i]=0x3ffffff;
memset(times,0,sizeof(times));
memset(inq,false,sizeof(inq));
for(i=0;i<=n;i++)//注意这里不都入队的话,图可能不连通,那么此时就有可能将无穷的漏掉
{
q[tail++]=i,inq[i]=true,times[i]++;
}
while(head!=tail)
{
inq[i=q[head]]=false;
head=(head+1)%110;
for(k=0;k<p[i].size();k++)
{
qq=p[i][k];
if(d[qq.v]>d[i]+qq.w)//要求d[qq.v]-d[i]<=qq.w,碰到大于更新
{
d[qq.v]=d[i]+qq.w;//所以此时d[qq.v]=d[i]+qq.w;
if(!inq[qq.v])
{
q[tail]=qq.v;
tail=(tail+1)%110;
inq[qq.v]=true;
if(++times[qq.v]>n+1) return false;
}
}
}
}
return true;
}
int main()
{
int m,i,j,u,v,w;
char s[10];
while(scanf("%d",&n)!=EOF)
{
if(!n) break;
scanf("%d",&m);
for(i=0;i<=n;i++)
p[i].clear();
/*for(i=0;i<n;i++)
{
qq.v=i+1;
qq.w=0;
p[i].push_back(qq);
}*/
for(i=0;i<m;i++)
{
scanf("%d%d%s%d",&u,&v,s,&w);
if(s[0]=='g')//d[u-1]-d[u+v]<=-w-1
{
qq.v=u-1;
qq.w=-w-1;
p[u+v].push_back(qq);
}
else//d[u+v]-d[u-1]<=w-1
{
qq.v=u+v;
qq.w=w-1;
p[u-1].push_back(qq);
}
}

if(SPFA()) printf("lamentable kingdom\n");
else printf("successful conspiracy\n");
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: