您的位置:首页 > 其它

【最短路 spfa && 水题】hdu-6201 transaction transaction transaction

2017-09-11 10:25 471 查看
Problem Description

你可以选择任意两个城市,在这个城市买书,另外一个城市卖书,让你求最大的利润,城市与城市之间的移动需要花费w

裸的spfa,比赛的时候,没好好想想,选择去想card那题了,所幸A出来了,原本自己能A的题目,还以为是自己不会的知识点的题目。比赛结束,圣昭一句话,瞬间懂了。

思路:

既然让你求任意两点的最大利润,正常想法就是,floyd看到城市数量有点多,肯定超时,发现边有点少,就思考一个超级汇点,到各个点的边权是该点买书的价格。那么这个点到所有点的最短路就可以求出来,最短路代表的就是原点到各个点所需要的成本。 遍历一遍所有点,求最大利润就好了。

#include<cstdio>
#include<cstring>
#include<queue>
using namespace std;
struct node
{
int to, w, next;
};
#define mm 100055
#define inf 0x3f3f3f3f
node Map[3 * mm];
int head[mm];
int dist[mm], vis[mm], n, a[mm];
void add(int u, int v, int w, int &cnt)//前向星建边
{
Map[cnt].to = v;
Map[cnt].w = w;
Map[cnt].next = head[u];
head[u] = cnt++;
}
void spfa(int u)//裸的spfa
{
memset(vis, 0, sizeof(vis));
memset(dist, inf, sizeof(dist));
queue<int> q;
q.
4000
push(u); vis[u] = 1;
dist[u] = 0;
while(!q.empty())
{
u = q.front(); q.pop();
vis[u] = 0;
for(int i = head[u]; ~i; i = Map[i].next)
{
int to = Map[i].to, w = Map[i].w;
if(dist[to] > dist[u] + w)
{
dist[to] = dist[u] + w;
if(!vis[to])
{
vis[to] = 1;
q.push(to);
}
}
}
}
int Max = 0;
for(int i = 1; i <= n; i++)//求最大利润
{
Max = max(Max, a[i] - dist[i]);
}
printf("%d\n", Max);
}
int main()
{
int T, i, u, v, w;
scanf("%d", &T);
while(T--)
{
scanf("%d", &n);
int cnt = 0;
memset(head, -1, sizeof(head));
memset(a, 0, sizeof(a));
for(i = 1; i <= n; i++)
{
scanf("%d", &a[i]);
add(0, i, a[i], cnt);//核心点,想到你就A了。
}
for(i = 1; i < n; i++)
{
scanf("%d %d %d", &u, &v, &w);
add(u, v, w, cnt);
add(v, u, w, cnt);
}
spfa(0);
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: