POJ 1511

大赛的题,题目叙述往往很花哨,考验阅读的准确获取信息和凝练能力

做这道题吃了很多系统知识不熟悉的亏,遇到了很多RE和TLE。

RE是因为想用一个类来保存,但是可惜这道题数据太大,开了GDB进去才发现segment fault的问题

TLE就非常玄学,后面参考Kuangbin的思路重新写才卡时间过。思路是没错的,正向记录图,然后再“逆转”每个边(这样可以将单目的节点最短路径问题转化为单源节点最短路径问题),只是开始读取输入的时候,一次记录两个的思路一直TLE。kuangbin的想法就是用到的时候我再重新构建一个图,开始我先把记录存起来。

此外,之前参考刘汝佳的模板,数据结构一直是利用强制转化的方法来构建临时变量(代码结合可理解这句话的涵义),Kuangbin的做法则是简单设置一个构造函数,结果表明确实会快一点。

之前一直习惯使用的memset也可能会出现时间不如循环快的问题,需要谨慎使用

最后要注意,因为这道题数据很大了,要开long long,记录ans才是合适的

总之这道题坑点太多了,数据考察的也很极限

#include <iostream>
#include <algorithm>
#include <queue>
#include <string>
#include <vector>
#include <cstdio>
#include <cstring>
#include <string>
#include <stack>
#include <map>
#include <set>
using namespace std;

const int maxp= 1e6+5;
const int INF= 0x3f3f3f3f;
typedef long long LL;

struct Edge
{
	int v;
	int c;
	Edge(int _v= 0, int _c= 0) : v(_v), c(_c) {}
};
struct HeapNode
{
	int u;
	int c;
	HeapNode(int _u= 0, int _c= 0) : u(_u), c(_c) {}
	int operator < (const HeapNode &rhs) const
	{
		return c> rhs.c;
	}
};
vector<Edge> G[maxp];
int A[maxp], B[maxp], C[maxp];
int dis[maxp], vis[maxp];

inline void AddEdge(int u, int v, int c)
{
	G[u].push_back(Edge(v, c));
}
void Dijkstra(int n, int s)
{
	for (int i= 1; i<= n; ++i){
		vis[i]= 0;
		dis[i]= INF;
	}
	priority_queue<HeapNode> Q;
	dis[s]= 0;
	Q.push(HeapNode(s, 0));
	HeapNode h;

	while (!Q.empty()){
		h= Q.top();
		Q.pop();
		int u= h.u;
		if (vis[u]){
			continue;
		}
		vis[u]= 1;

		int esz= G[u].size();
		for (int i= 0; i< esz; ++i){
			int v= G[u][i].v;
			int c= G[u][i].c;
			if (!vis[v] && dis[v]> dis[u]+c){
				dis[v]= dis[u]+c;
				Q.push(HeapNode(v, dis[v]));
			}
		}
	}
}

int main()
{
	int kase;
	scanf("%d", &kase);

	while (kase--){
		int p, q;
		scanf("%d %d", &p, &q);
		for (int i= 0; i< q; ++i){
			scanf("%d %d %d", A+i, B+i, C+i);
		}
		for (int i= 1; i<= p; ++i){
			G[i].clear();
		}
		for (int i= 0; i< q; ++i){
			AddEdge(A[i], B[i], C[i]);
		}
		Dijkstra(p, 1);
		LL ans= 0;
		for (int i= 1; i<= p; ++i){
			ans+= dis[i];
		}
		for (int i= 0; i<= p; ++i){
			G[i].clear();
		}
		for (int i= 0; i< q; ++i){
			AddEdge(B[i], A[i], C[i]);
		}
		Dijkstra(p, 1);
		for (int i= 1; i<= p; ++i){
			ans+= dis[i];
		}

		printf("%lld\n", ans);
	}

	return 0;
}
posted @ 2021-04-11 14:29  IdiotNe  阅读(39)  评论(0编辑  收藏  举报