题意:
题解:
这个题其实是差分约束的裸题,但是有几个坑要注意
1.题目说了,奶牛按照编号1…N排列,对于ML个输入,A< B
,所以关系是B - A < 10,而不是A - B <10,我一开始看反了。。导致一直wa
2.题目没说图连通,所以要么每个点都跑一遍spfa,要么建一个超级源点0,0到其他n个点的距离是0,从0跑,这样所有点都在一个连通块内
3,题目要求三种情况,第一个是没有方案,第二个是有合法方案,但是距离无穷远,第三个是有合法方案,且不是无穷远。所以一遍spfa是不足够的,因为第一种情况要判断负环,负环的优先级是最高的,所以先跑一个spfa(0),然后再判断情况2,3,再跑spfa(1)
代码:
代码最后一个点wa了不知道为什么。。。
对拍也没找到错误,哭了,,
我的代码:
#include<bits/stdc++.h>
typedef long long ll;
using namespace std;
inline int read(){
int s=0,w=1;
char ch=getchar();
while(ch<'0'||ch>'9'){if(ch=='-')w=-1;ch=getchar();}
while(ch>='0'&&ch<='9') s=s*10+ch-'0',ch=getchar();//s=(s<<3)+(s<<1)+(ch^48);
return s*w;
}
const int maxn=4e4+9;
struct node{
int v,w;
};
int n,ml,md;
vector<node>edge[maxn];
int dis[maxn],vis[maxn];
int cnt[maxn];
void spfa(int now)
{
for(int i=1;i<=n;i++)dis[i]=1e9+7;
memset(vis,0,sizeof(vis));
memset(cnt,0,sizeof(cnt));
vis[now]=1;
queue<int>q;
dis[now]=0;
q.push(now);
while(!q.empty())
{
int u=q.front();
q.pop();
vis[u]=0;
for(int i=0;i<edge[u].size();i++)
{
int v=edge[u][i].v;
int w=edge[u][i].w;
if(dis[v]>dis[u]+w)
{
dis[v]=dis[u]+w;
cnt[v]=cnt[u]+1;
if(cnt[v]>=n+1)
{
puts("-1");
exit(0);
//return 1;//存在负环
}
if(vis[v]==0)
{
q.push(v);
vis[v]=1;
}
}
}
}
//return 0;
}
int main()
{
cin>>n>>ml>>md;
int a,b,d;
for(int i=1;i<=n;i++)
{
edge[0].push_back(node{i,0});
}
for(int i=1;i<=ml;i++)
{
cin>>a>>b>>d;
edge[a].push_back(node{b,d});
}
for(int i=1;i<=md;i++){
cin>>a>>b>>d;
edge[b].push_back(node{a,-d});
}
spfa(0);
spfa(1);
if(dis[n]==1e9+7)cout<<-2<<endl;
else cout<<dis[n]<<endl;
return 0;
}
/*
4 2 1
1 3 10
2 4 20
2 3 3
*/
正确的代码:
#include <bits/stdc++.h>
#define INF 0x3f3f3f3f
#define main mian
using namespace std;
const int N=1005;
const int M=40005;
int n,ml,md,a,b,d;
struct EDGE
{
int nxt,to,wei,;
}edge[M];
int head[N],tot;
inline void add(int x,int y,int v)
{
edge[++tot].nxt=head[x];
edge[tot].to=y;
edge[tot].wei=v;
head[x]=tot;
}
queue<int> q;
int vis[N],dis[N],circle[N];
void spfa(int s)
{
memset(dis,0x3f,sizeof(dis));
memset(vis,0,sizeof(vis));
memset(circle,0,sizeof(circle));
q.push(s);
vis[s]=1,dis[s]=0;
while(!q.empty())
{
int now=q.front(); q.pop(); vis[now]=0;
for(int i=head[now];i;i=edge[i].nxt)
{
int tt=edge[i].to;
if(dis[now]+edge[i].wei<dis[tt])
{
dis[tt]=dis[now]+edge[i].wei;
circle[tt]=circle[now]+1;
if(circle[tt]>=n)
{
puts("-1");exit(0);
}
if(!vis[tt])
{
vis[tt]=1;
q.push(tt);
}
}
}
}
}
int main()
{
int n;
scanf("%d%d%d",&n,&ml,&md);
for(int i=1;i<=n;i++) add(0,i,0);
for(int i=1;i<=ml;i++)
{
scanf("%d%d%d",a,b,d);
add(a,b,d);
}
for(int i=1;i<=md;i++)
{
scanf("%d%d%d",a,b,d);
add(b,a,-d);
}
spfa(0);
spfa(1);
if(dis[n]==INF) puts("-2");
else printf("%d",dis[n]);
return 0;
}