usaco布局(差分约束系统的应用)

题目的正解

很明显可以看出是差分约束系统的题目,1:如果A和B距离至多为D则建边A->B权值为D,2:距离至少为D则建边B->A权值为-D。然后最短路。若有负权环则输出-1,若无法到达点N则输出-2,否则直接输出1~N的距离即可。

代码

#include<cstdio>
#include<algorithm>
#include<iostream>
#include<cstdlib>
#include<cstring>
#include<string>
#include<cmath>
#include<queue>

using namespace std;

const int maxn=2002;
const int inf=0x3f3f3f3f;

struct
{
	int pre,v,c;
}edge[1000009];

int kk,head[maxn],ml,mn,dist[maxn],y[maxn],n;
bool b[maxn];
void addedge(int u,int v,int c)
{
	kk++;edge[kk].v=v;edge[kk].c=c;edge[kk].pre=head[u];head[u]=kk;
}
int main()
{
	scanf("%d%d%d",&n,&ml,&mn);
	for (int i=1;i<=ml;i++)
	{
		int a,b,c;
		scanf("%d%d%d",&a,&b,&c);
		addedge(a,b,c);
	}
	for (int i=1;i<=mn;i++)
	{
		int a,b,c;
		scanf("%d%d%d",&a,&b,&c);
		addedge(b,a,-c); 
	}//建图
	bool k=true;
	queue<int> q;
	memset(dist,inf,sizeof(dist));
	dist[1]=0;y[1]=1;b[1]=true;
	q.push(1);
	while (!q.empty())
	{
		int r=q.front();
		q.pop();
		for (int i=head[r];i;i=edge[i].pre)
		{
			int vv=edge[i].v,cc=edge[i].c;
			if (dist[r]+cc<dist[vv])
			{
				dist[vv]=dist[r]+cc;
				if (!b[vv]) 
				{
					y[vv]++;
					if (y[vv]==n) //判断负环
					{
						k=false;
						break;
					}
					b[vv]=true;
					q.push(vv);
				}
			}
		}
		if (!k) break;
		b[r]=false;
	} // spfa最短路
	if (!k) printf("-1");
	else if (dist[n]!=inf) printf("%d",dist[n]);
	else printf("-2");
	return 0;
}



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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值