这题就是裸的差分约束,但是特殊情况的判定值得学习。
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;
}