洛谷P10110 [GESP202312 七级] 商品交易
题目
传送门
题意
给定你n种商品和他们的价值,要你在M个商人的交易中,用你持有的商品a获得你希望获得的商品b,并且求最小花费,找不到输出No solution,并且我们观察样例可以发现有负边权。
思路
毫无疑问,这个一眼就是最短路。由于有负边权,所以我们可以用SPFA。
难点
边的权值,例如x可以置换y那么我们边的权值为a[y]-a[x]+1,这里加一是手续费
代码
有注释版
#include<bits/stdc++.h>
using namespace std;
struct edge{
long long from,to,len,next;
};
long long n,e,k,qs,zd;
edge a[200005];
long long p[100005];
long long d[100005];
long long d1[100005];
queue<long long> q;
bool f[20010];
void add(int x,int y){
k++;
a[k].from=x;
a[k].to=y;
a[k].len=d1[y]-d1[x]+1;//刚刚的难点
a[k].next=p[x];//邻接表
p[x]=k;//邻接表
}
void spfa(){
memset(d,0x3f3f,sizeof(d));
d[qs]=0;//初始化启始点
q.push(qs);//同理
f[qs]=true;//同理
while(q.size()!=0){
int h=q.front();
for(int i=p[h];i!=0;i=a[i].next){//遍历可以去的边
int to=a[i].to;
if(d[h]+a[i].len<d[to]){//如果更优
d[to]=d[h]+a[i].len;//替代
if(f[to]==0){//说明y点不在队列
q.push(to);//入队
f[to]=true; //标记
}
}
}
f[h]=false;//出队标记
q.pop();
}
}
int main(){
std::ios::sync_with_stdio(false);//关闭输入输出流
std::cin.tie(0);
std::cout.tie(0);
cin>>n>>e>>qs>>zd;
for(int i=0;i<n;i++){
cin>>d1[i];
}
for(int i=1;i<=e;i++){
int x,y;
cin>>x>>y;
add(x,y);//建图
}
spfa();
if(d[zd]>=0x3f3f)cout<<"No solution";//不能找到
else cout<<d[zd];
return 0;
}
无注释版
#include<bits/stdc++.h>
using namespace std;
struct edge{
long long from,to,len,next;
};
long long n,e,k,qs,zd;
edge a[200005];
long long p[100005];
long long d[100005];
long long d1[100005];
queue<long long> q;
bool f[20010];
void add(int x,int y){
k++;
a[k].from=x;
a[k].to=y;
a[k].len=d1[y]-d1[x]+1;
a[k].next=p[x];
p[x]=k;
}
void spfa(){
memset(d,0x3f3f,sizeof(d));
d[qs]=0;
q.push(qs);
f[qs]=true;
while(q.size()!=0){
int h=q.front();
for(int i=p[h];i!=0;i=a[i].next){
int to=a[i].to;
if(d[h]+a[i].len<d[to]){
d[to]=d[h]+a[i].len;
if(f[to]==0){
q.push(to);
f[to]=true;
}
}
}
f[h]=false;
q.pop();
}
}
int main(){
std::ios::sync_with_stdio(false);
std::cin.tie(0);
std::cout.tie(0);
cin>>n>>e>>qs>>zd;
for(int i=0;i<n;i++){
cin>>d1[i];
}
for(int i=1;i<=e;i++){
int x,y;
cin>>x>>y;
add(x,y);
}
spfa();
if(d[zd]>=0x3f3f)cout<<"No solution";
else cout<<d[zd];
return 0;
}

浙公网安备 33010602011771号