zoukankan      html  css  js  c++  java
  • 题解【LOJ3087】「GXOI / GZOI2019」旅行者

    题面

    对正图和反图分别跑一次最短路,求出离每个点最近的关键点。

    对于每一条边,如果离两个端点最近的点不同,那么与答案取 (min) 即可。

    类似的题目有 牛客 IOI 周赛19 - 提高组 A. 基站

    代码可以参考一下,毕竟这也是一类经典套路。

    #include <bits/stdc++.h>
    #define DEBUG fprintf(stderr, "Passing [%s] line %d
    ", __FUNCTION__, __LINE__)
    #define File(x) freopen(x".in","r",stdin); freopen(x".out","w",stdout)
    
    using namespace std;
    
    typedef long long LL;
    typedef pair <int, int> PII;
    typedef pair <LL, int> PLI;
    typedef pair <int, PII> PIII;
    
    template <typename T>
    inline T gi()
    {
    	T f = 1, x = 0; char c = getchar();
    	while (c < '0' || c > '9') {if (c == '-') f = -1; c = getchar();}
    	while (c >= '0' && c <= '9') x = x * 10 + c - '0', c = getchar();
    	return f * x;
    }
    
    const int INF = 0x3f3f3f3f, N = 100003, M = 1000003;
    
    int T, n, m, k;
    int tot, head[N], headc[N], ver[M], nxt[M], edge[M];
    int g[2][N];
    LL dis[2][N];
    bool vis[N], isk[N];
    LL ans;
    
    inline void add(int h[], int u, int v, int w) {ver[++tot] = v, edge[tot] = w, nxt[tot] = h[u], h[u] = tot;}
    
    inline void Dij(bool fl)
    {
    	priority_queue <PLI> q;
    	memset(dis[fl], 0x3f, sizeof dis[fl]); memset(vis, false, sizeof vis);
    	for (int i = 1; i <= n; i+=1) if (isk[i]) q.push({0, i}), dis[fl][i] = 0, g[fl][i] = i;
    	while (!q.empty())
    	{
    		int u = q.top().second; q.pop();
    		if (vis[u]) continue; vis[u] = true;
    		for (int i = fl ? headc[u] : head[u]; i; i = nxt[i])
    		{
    			int v = ver[i], w = edge[i];
    			if (dis[fl][v] > dis[fl][u] + w)
    			{
    				dis[fl][v] = dis[fl][u] + w;
    				g[fl][v] = g[fl][u];
    				q.push({-dis[fl][v], v});
    			}
    		}
    	}
    }
    
    int main()
    {
    //	File("");
    	T = gi <int> ();
    	while (T--)
    	{
    		n = gi <int> (), m = gi <int> (), k = gi <int> ();
    		memset(head, 0, sizeof head); memset(headc, 0, sizeof headc); tot = 0;
    		for (int i = 1; i <= m; i+=1)
    		{
    			int u = gi <int> (), v = gi <int> (), w = gi <int> ();
    			add(head, u, v, w), add(headc, v, u, w);
    		}
    		for (int i = 1; i <= n; i+=1) isk[i] = false;
    		for (int i = 1; i <= k; i+=1) isk[gi <int> ()] = true;
    		ans = 1e18;
    		Dij(0); Dij(1);
    		for (int u = 1; u <= n; u+=1)
    			for (int i = head[u]; i; i = nxt[i])
    			{
    				int v = ver[i];
    				if (g[0][u] != g[1][v]) ans = min(ans, edge[i] + dis[0][u] + dis[1][v]);
    			}
    		printf("%lld
    ", ans);
    	}
    	return 0;
    }
    
  • 相关阅读:
    toj 2975 Encription
    poj 1797 Heavy Transportation
    toj 2971 Rotating Numbers
    zoj 2281 Way to Freedom
    toj 2483 Nasty Hacks
    toj 2972 MOVING DHAKA
    toj 2696 Collecting Beepers
    toj 2970 Hackle Number
    toj 2485 Card Tric
    js页面定位,相关几个属性
  • 原文地址:https://www.cnblogs.com/xsl19/p/14085004.html
Copyright © 2011-2022 走看看