题意:n头奶牛按顺序站,可以重合,给出ml对奶牛之间的最大距离和md对奶牛之间的最小距离,求牛1和牛n之间的最大距离。
典型的差分约束题,根据题意可得到三个条件。
1.dj-di>=0 (j>i 以下略),可转换成 di-dj<=0
2.对ml对奶牛 dj-di<=D
3.对md对奶牛 dj-di>=D,可转换成 di-dj<=-D
然后根据不等式做有向边,再用spfa求最短路径得解。
然而这题反复提交了好多次,发现原题的数据错了,没有考虑到dj-di>=0这个条件。
如以下数据:
4 2 1
1 2 10
2 4 10
2 3 11
输出应该为-1,AC代码输出20。
AC代码,未考虑上述条件
#include <iostream>
#include<cstdio>
#include<cstring>
#include<cmath>
#define INF 0x7fffffff
#define N 5000
using namespace std;
struct node
{
int to,next,w;
}e[N*8];
int head[N],cnt,n,num[N],d[N],v[N],q[N];
void addedge(int u,int v,int w)
{
e[cnt].to=v;
e[cnt].w=w;
e[cnt].next=head[u];
head[u]=cnt++;
}
int spfa()
{
for(int i=1;i<=n;i++)
num[i]=v[i]=0,d[i]=INF;
int k=0;
q[k++]=v[1]=num[1]=1;
d[1]=0;
while(k)
{
int t=q[--k];
v[t]=0;
for(int i=head[t];i!=-1;i=e[i].next)
{
int c=e[i].to;
if(d[c]>d[t]+e[i].w)
{
d[c]=d[t]+e[i].w;
if(!v[c])
{
if(++num[c]>n) return -1;
q[k++]=c;
v[c]=1;
}
}
}
}
if(d[n]==INF) return -2;
return d[n];
}
int main()
{
int m1,m2;
cin>>n>>m1>>m2;
memset(head,-1,sizeof(head));
cnt=0;
for(int i=1;i<=m1;i++)
{
int u,v,w;
scanf("%d%d%d",&u,&v,&w);
addedge(u,v,w);
}
for(int j=1;j<=m2;j++)
{
int u,v,w;
scanf("%d%d%d",&u,&v,&w);
addedge(v,u,-w);
}
cout<<spfa()<<endl;
}
加上条件后WA
#include <iostream>
#include<cstdio>
#include<cstring>
#include<cmath>
#define INF 0x7fffffff
#define N 5000
using namespace std;
struct node
{
int to,next,w;
}e[N*8];
int head[N],cnt,n,num[N],d[N],v[N],q[N];
void addedge(int u,int v,int w)
{
e[cnt].to=v;
e[cnt].w=w;
e[cnt].next=head[u];
head[u]=cnt++;
}
int spfa()
{
for(int i=1;i<=n;i++)
num[i]=v[i]=0,d[i]=INF;
int k=0;
q[k++]=v[1]=num[1]=1;
d[1]=0;
while(k)
{
int t=q[--k];
v[t]=0;
for(int i=head[t];i!=-1;i=e[i].next)
{
int c=e[i].to;
if(d[c]>d[t]+e[i].w)
{
d[c]=d[t]+e[i].w;
if(!v[c])
{
if(++num[c]>n) return -1;
q[k++]=c;
v[c]=1;
}
}
}
}
if(d[n]==INF) return -2;
return d[n];
}
int main()
{
int m1,m2;
cin>>n>>m1>>m2;
memset(head,-1,sizeof(head));
cnt=0;
for(int i=1;i<n;i++) addedge(i+1,i,0);//仅加了这一个条件
for(int i=1;i<=m1;i++)
{
int u,v,w;
scanf("%d%d%d",&u,&v,&w);
addedge(u,v,w);
}
for(int j=1;j<=m2;j++)
{
int u,v,w;
scanf("%d%d%d",&u,&v,&w);
addedge(v,u,-w);
}
cout<<spfa()<<endl;
}
若发现错误敬请指出。