记录编号 345067 评测结果 AAAAAAAAAA
题目名称 通向聚会的套路 最终得分 100
用户昵称 Gravatar小e 是否通过 通过
代码语言 C++ 运行时间 0.993 s
提交时间 2016-11-10 19:16:11 内存使用 2.38 MiB
显示代码纯文本
// 建反图, 从n点求出到各个点的最短距离
// 注意原来的odd变成了even

#include <cstdio>
#include <cstring>
#include <algorithm>
#include <iostream>
#include <queue>
using namespace std;

const int maxnumber = 10010, inf = 0x3f3f3f3f;
int n, m;
struct Edge
{
	int to, w, next;
	int odd, even;
	inline Edge(): odd(0), even(0) {}
}edges[maxnumber * 10];
string house[maxnumber];
int head[maxnumber], tot;
int dis[maxnumber][2];// dis[i][0]: 走过奇数个点到达i的最短距离
struct Node
{
	int pos, tot, type;// type: 已经走过的点的个数的奇偶
	inline Node(const int& a, const int& b, const int& c): pos(a), tot(b), type(c) {}
	inline bool operator < (const Node& a) const { return tot > a.tot; }
};
priority_queue <Node> Q;

inline void AddEdge(const int& from, const int& to, const int& w)
{
	edges[++tot].to = to;
	edges[tot].w = w;
	edges[tot].next = head[from];
	head[from] = tot;
}

inline void Dijkstra()
{
	memset(dis, 0x3f, sizeof dis);
	dis[n][1] = dis[n][0] = 0;
	Q.push(Node(n, 0, 0)); Q.push(Node(n, 0, 1));
	while (!Q.empty()) {
		Node top = Q.top(); Q.pop();
		int pos = top.pos, tot = top.tot, type = top.type;
		if (tot != dis[pos][type]) continue;
		for (int i = head[pos]; i; i = edges[i].next) {
			int to = edges[i].to, w = edges[i].w, odd = edges[i].odd, even = edges[i].even;
			if (!type && odd)
				if (dis[to][type ^ 1] > dis[pos][type] + w) {
					dis[to][type ^ 1] = dis[pos][type] + w;
					Q.push(Node(to, dis[to][type ^ 1], type ^ 1));
				}
			if (type && even)
				if (dis[to][type ^ 1] > dis[pos][type] + w) {
					dis[to][type ^ 1] = dis[pos][type] + w;
					Q.push(Node(to, dis[to][type ^ 1], type ^ 1));
				}
			if (!even && !odd)
				if (dis[to][type ^ 1] > dis[pos][type] + w) {
					dis[to][type ^ 1] = dis[pos][type] + w;
					Q.push(Node(to, dis[to][type ^ 1], type ^ 1));
				}
		}
	}
	// for (int i = 1; i <= n; ++i)
	// 	printf("dis[%d]:%d %d\n", i, dis[i][0], dis[i][1]);
}

#define SUBMIT
int main(int argc, char const *argv[])
{
#ifdef SUBMIT
	freopen("party_ezoi.in", "r", stdin); freopen("party_ezoi.out", "w", stdout);
#endif

	int from, to, w, p, num;
	int ans = inf;
	string ch;
	scanf("%d%d", &n, &m);
	for (int i = 1; i <= m; ++i) {
		scanf("%d%d%d", &from, &to, &w);
		AddEdge(to, from, w);
	}
	scanf("%d", &p);
	while (p--) { scanf("%d", &num); edges[num].even = 1; }// 奇偶相反
	scanf("%d", &p);
	while (p--) { scanf("%d", &num); edges[num].odd = 1; }
	scanf("%d", &p);
	while (p--) { scanf("%d", &num); cin >> house[num]; }

	Dijkstra();

	for (int i = 1; i <= n; ++i)
		if (!house[i].empty()) ans = min(ans, dis[i][1]);
	for (int i = 1; i <= n; ++i) {
		if (dis[i][1] == ans && !house[i].empty()) {
			if (ch.empty()) ch = house[i];
			else ch = min(ch, house[i]);
		}
	}
	cout << ch << endl;
	printf("%d\n", ans);

#ifndef SUBMIT
	printf("\n----------\n");
	getchar(); getchar();
#else
	fclose(stdin); fclose(stdout);
#endif

	return 0;
}