bzoj1731(差分约束系统,重点!)

这题就是裸的差分约束,但是特殊情况的判定值得学习。

1:

文中说“如果不存在满足要求的方案,输出-1;”

bzoj2330中也说“如果不能满足小朋友们的所有要求,就输出-1。”

不满足要求,在这类题中就表示,题目的信息是有矛盾的。

其实就是,如果我们发现了负环,就说明:题目的信息有矛盾!


2:

文中说 "如果1号奶牛和N号奶牛间的距离可以任意大,输出-2"

就是说信息无法限制1到n 的距离,在求最大距离中会出现无限大,求最小距离中会出现无限小

这种情况应该是,dis【n】==inf,其实,dis【i】就1与i的最大距离,既然是inf,就是无限大了(这是根据定义)

感觉,dis【n】==inf,就代表连边根本连不到n号节点,及约束不到n号节点,自然是无限大了


#include<cstdio>
#include<cmath>
#include<queue>
#include<cstring>
#include<cstdlib>
#include<algorithm>
using namespace std;
typedef long long ll;
const ll inf=10000000000ll;
const int N=12005;

int n,ml,md;
int head[N],tot,tt[N];
ll dis[N];
struct aa
{
	int to,pre;
	ll dis;
}edge[N*4];
void addedge(int x,int y,ll dis)
{
	edge[++tot].to=y;edge[tot].dis=dis;edge[tot].pre=head[x];head[x]=tot;
}

bool b[N];

ll spfa()
{
	for (int i=2;i<=n;i++) dis[i]=inf;
	dis[1]=0;b[1]=true;
	queue<int> q;
	q.push(1);
	while (!q.empty())
	{
		int u=q.front();q.pop();
		
		for (int i=head[u];i;i=edge[i].pre)
		if (dis[edge[i].to]>dis[u]+edge[i].dis)
		{
			int v=edge[i].to;
			dis[v]=dis[u]+edge[i].dis;
			
			tt[v]++;
			if (tt[v]==n) return -1;
			
			if (!b[v]) {b[v]=true;q.push(v);}
		}
		b[u]=false;
	}
	if (dis[n]==inf) return -2;
	return dis[n];
}

int main()
{
	scanf("%d%d%d",&n,&ml,&md);
	int A,B;
	ll d;
	
	for (int i=1;i<=ml;i++)
	{
		scanf("%d%d%lld",&A,&B,&d);
		addedge(A,B,d);
	}
	for (int i=1;i<=md;i++)
	{
		scanf("%d%d%lld",&A,&B,&d);
		addedge(B,A,-d);
	}
	
	printf("%lld",spfa());
	return 0;
}


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值