千万别点进来,点进来你就哭了
Time limit 2000 ms
题目链接https://csustacm.fun/problem/1089
Description
PY利用寒假摸鱼时间去了一趟香港吃吃吃,下面就由我介绍一下我遇到的好吃的香港美食。
首先介绍第一家合益泰小食,这家主打肠粉,这家的肠粉特别的正宗,价格非常亲民,口感非常好
公和荳品厂,这家的豆腐花特别好吃,超级嫩,口感又香又滑。
添好运——这是一家港式点心店,我推荐吃这里的糯米鸡和凤爪,口感都非常好,这里的虾饺也很好吃。
不过叉烧包太甜了,甜到我受不了了。
最后推荐一个华星冰室,不能多写了,不然题面写不下了。这里我极力推荐这家店的奶茶,
奶和茶混合的刚刚好的样子,没有以前我喝的以前的奶茶的那种过分甜,一点茶的味道都没有。(喝过很多奶茶,一个个都甜的不得了)
下面开始PY的香港之行,PY有n个要去的小吃店,这n个小吃店被m条路径联通起来。
PY有1个传送石和n-1个传送石碎片。
PY可以用传送石标记一个小吃店作为根据地。
每当PY吃完一个地点的美食,必须回到根据地(传送石标记的小吃店)休息一段时间,才能去另外一个小吃店。
也就是说你从根据地走去另一个小吃店吃完之后,不需要再走回来,用传送石碎片即可回来。
现在PY想知道他该标记那个小吃店才能让她走最短的路程吃完这nn个小吃店?
请聪明的你思考上述问题,并告诉他所需走的路程总和 和 他该标记那个地点作为根据地。
ps.传送石只能标记一个小吃店。
Input
第一行输入T,表示有T组数据。
每组数据第一行输入两个整数n,m,表示n家小吃店,有m条路径(1<=n<=1000 , 1<=m<=10000)
接下来m行,每行33个整数u,v,w 表示第u家小吃店到第v家小吃店有一条长度为w米的路径。(0<=w<=4e5),数据保证u!=v。
Output
输出两个整数 PY需要最少走多远才能吃完这n个小吃店的距离 和 被传送石标记的小吃店的标号。
如果距离相同,输出标号最小的。保证至少存在一个解
Sample Input 1
2
3 2
1 2 1
2 3 2
3 2
1 2 1
2 3 2
Sample Output 1
3 2
3 2
Hint
最优解:
标记2号点位根据地。从点2走到点1距离为1,然后利用传送石碎片回到根据地,再从点2走到点3距离为2,然后利用传送石碎片回到根据地,总距离和为3。
题目很详细。。。简单来说就是要跑最短路,枚举每一个点为起点,跑一遍最短路,求出所有点到起点的最短路,然后更新ans就OK了>~ ~<
当然普通的最短路肯定会超时,所以就用到了堆优化。。。最好的话用dj算法,1s内过
#include <cstdio>
#include <cstring>
#include <iostream>
#include <queue>
#define inf 999999999
#define ll long long
#define mac 1100
using namespace std;
int n, m;
struct node {
int to, cost;
};
struct node2 {
int id, d;
bool friend operator < (node2 n1, node2 n2) {
return n1.d > n2.d;
}
};
vector<node>g[mac];
ll vis[mac];
ll dis[mac];
void myinit();
ll dj(int s);
void mst();
int main() {
int i, j, x, y, c, s, t;
while (scanf("%d%d", &n, &m)!=EOF) {
myinit();
for(i = 1; i <= m; i++) {
scanf("%d%d%d", &x, &y, &c);
node n1, n2;
n1.to = x;
n1.cost = c;
n2.to = y;
n2.cost = c;
g[x].push_back(n2);
g[y].push_back(n1);
}
ll mark,mans=inf;
for (int i=1; i<=n; i++) {
mst();
ll ok=dj(i);
if (ok<mans) {
mans=ok;
mark=i;
}
}
printf ("%lld %lld\n",mans,mark);
}
return 0;
}
void myinit() {
memset(vis, 0, sizeof(vis));
for(int i = 0; i <mac; i++) {
g[i].clear();
}
for (int i=1; i<=n; i++) dis[i]=inf;
}
ll dj(int s) {
priority_queue<node2> q;
dis[s] = 0;
node2 nn1;
nn1.id = s;
nn1.d = dis[s];
q.push(nn1);
while(!q.empty()) {
node2 nn2 = q.top();
q.pop();
int now = nn2.id;
if(vis[now])continue;
else vis[now] = 1;
for(int i = 0; i < g[now].size(); i++) {
if(!vis[g[now][i].to] && g[now][i].cost + dis[now] < dis[g[now][i].to]) {
dis[g[now][i].to] = g[now][i].cost + dis[now];
node2 nn3;
nn3.id = g[now][i].to;
nn3.d = dis[g[now][i].to];
q.push(nn3);
}
}
}
ll sans=0;
for (int i=1; i<=n; i++) sans+=dis[i];
return sans;
}
void mst() {
for (int i=1; i<=n; i++) dis[i]=inf;
memset(vis, 0, sizeof(vis));
}