上文说到moxin跟郭先生去看电影了,于是moxin又双叒破产了,无奈之下moxin只能又做起了卖菜的生意
当然卖菜就得进货,于是moxin就去进货了,这里的商店比较奇葩,遵守以下规则:
1.当两种不同的菜有着相同的价值的时候,那么可以进行交换(比如a种菜的价值等于b种菜的价值,那么a种菜可以与b种菜互相交换,互相交换是不需要花费额外的价值)
2.可以通过讨价还价,以一种菜的价值 + x价值RMB 来换取另一种菜
3.可以直接使用等于菜的价值RMB来购买一种菜
那么问题来了,moxin想要知道购买每一种菜最少需要花费多少RMB?
Input
第一行输入T(1<=T<=10),代表有T组
第二行输入n,m(2<=n<=1e3, 0<=m<=1e3)
代表有n种菜,m种讨价还价的关系
接下来n行,每行有两个整数a,b(1<=a<=n, 1<=b<=1e5)
代表n种菜,第a种菜的价值为b
接下来m行,每行有三个整数a,b,c(1<=a<=n, 1<=b<=n, 1<=c<=1e5, a != b)
代表a种菜+价值为c的RMB可以换取b种菜
(数据一共7组)
Output
n行
每行只有一个整数,每行的整数代表对应的第i种菜所需的最小花费
SampleInput
1
3 1
1 7
2 2
3 2
1 3 1
SampleOutput
7
2
2
题意:可以通过三种途径来使得获得某种菜的价值更小,求获得全部菜的最小花费
思路:思维最短路径好题 根据每种菜之间的关系建图然后跑dijstra得到答案 ,较难的点在于建图 具体看代码注释
一开始没看范围暴力手搓Floyd然后就赠送了我衣个大大的TLE
#include <iostream>
#include <cstring>
#include <algorithm>
#include <queue>
#include <cstdio>
using namespace std;
typedef pair<int,int> p;
const int maxn=1e3+5;
const int inf=0x3f3f3f3f;
int n,m;
struct edge
{
int to;
int cost;
edge(int tt,int cc):to(tt),cost(cc){}
};
int dist[maxn];
int vis[maxn];
vector<edge>g[maxn];
void dj(int s)///di就不多说了 套板子就行
{
fill(dist,dist+n+1,inf);
priority_queue<p,vector<p>,greater<p> >que;
dist[s]=0;
que.push(p(0,s));
while(!que.empty())
{
p now=que.top();
que.pop();
int temp=now.second;
if(now.first>dist[temp])
continue;
for(int i=0; i<g[temp].size(); i++)
{
edge next=g[temp][i];
if(dist[next.to]>dist[temp]+next.cost)
{
dist[next.to]=dist[temp]+(int)next.cost;
que.push(p(dist[next.to],next.to));
}
}
}
}
int main()
{
int t;
scanf("%d",&t);
while(t--)
{
scanf("%d%d",&n,&m);
memset(vis,0,sizeof(vis));///初始化
for(int i=0; i<=n; ++i)
g[i].clear();
int a,b,c;
for(int i=0; i<n; ++i)
{
scanf("%d%d",&a,&b);
vis[a]=b;
g[0].push_back(edge(a,b));///a种菜的价值为b
}
for(int i=0; i<m; ++i)
{
scanf("%d%d%d",&a,&b,&c);
g[a].push_back(edge(b,c));///可以通过a种菜的花费c元得到b种菜
}
for(int i=1; i<=maxn; ++i)
{
for(int j=1; j<=maxn; ++j)
{
if(vis[i]!=0 && i!=j &&vis[i]==vis[j])///不同的菜有相同的价值是可以互换,那就在相同价值的a,b两种菜之间建立一条权值为0的边
{
g[i].push_back(edge(j,0));
g[j].push_back(edge(i,0));
}
}
}
dj(0);
for(int i=1; i<maxn; ++i)///输出即可
{
if(vis[i])
printf("%d\n",dist[i]);
}
}
return 0;
}