zoukankan      html  css  js  c++  java
  • DIjkstra(反向边) POJ 3268 Silver Cow Party || POJ 1511 Invitation Cards

    题目传送门 1 2

    题意:有向图,所有点先走到x点,在从x点返回,问其中最大的某点最短路程

    分析:对图正反都跑一次最短路,开两个数组记录x到其余点的距离,这样就能求出来的最短路以及回去的最短路.

    POJ 3268

    //#include <bits/stdc++.h>
    #include <cstdio>
    #include <queue>
    #include <algorithm>
    #include <cstring>
    using namespace std;
    
    typedef long long ll;
    const int N = 1e6 + 5;
    const int E = N;
    const int INF = 0x3f3f3f3f;
    struct Edge	{
    	int u, v, w, nex;
    	Edge() {}
    	Edge(int u, int v, int w, int nex) : u (u), v (v), w (w), nex (nex) {}
    	bool operator < (const Edge &r)	const	{
    		return w > r.w;
    	}
    }edge[2][E];
    int head[N];
    int d[2][N];
    bool vis[N];
    int n, m, x, e;
    
    inline int read(void)	{
    	int f = 1, ret = 0;	char ch = getchar ();
    	while (ch > '9' || ch < '0')	{
    		if (ch == '-')	f = -1;
    		ch = getchar ();
    	}
    	while (ch <= '9' && ch >= '0')	{
    		ret = ret * 10 + ch - '0';
    		ch = getchar ();
    	}
    	return ret * f;
    }
    
    void init(void)	{
    	memset (head, -1, sizeof (head));
    	e = 0;
    }
    
    void add_edge(int u, int v, int w)	{
    	edge[0][e] = Edge (u, v, w, head[u]);
    	head[u] = e++;
    }
    
    void build_re_graph(void)	{
    	memset (head, -1, sizeof (head));
    	e = 0;
    	for (int i=0; i<m; ++i)	{
    		edge[1][e] = Edge (edge[0][i].v, edge[0][i].u, edge[0][i].w, head[edge[0][i].v]);
    		head[edge[0][i].v] = e++;
    	}
    }
    
    void SPFA(int s, int tp)	{
    	memset (d[tp], INF, sizeof (d[tp]));
    	memset (vis, false, sizeof (vis));
    	d[tp][s] = 0;	vis[s] = true;
    	queue<int> que;	que.push (s);
    	while (!que.empty ())	{
    		int u = que.front ();	que.pop ();
    		vis[u] = false;
    		for (int i=head[u]; ~i; i=edge[tp][i].nex)	{
    			int v = edge[tp][i].v, w = edge[tp][i].w;
    			if (d[tp][v] > d[tp][u] + w)	{
    				d[tp][v] = d[tp][u] + w;
    				if (!vis[v])	{
    					vis[v] = true;	que.push (v);
    				}
    			}
    		}
    	}
    }
    
    void Dijkstra(int s, int tp)	{
    	memset (vis, false, sizeof (vis));
    	memset (d[tp], INF, sizeof (d[tp]));	d[tp][s] = 0;
    	priority_queue<Edge> que;	que.push (Edge (0, s, d[tp][s], 0));
    	while (!que.empty ())	{
    		int u = que.top ().v;	que.pop ();
    		if (vis[u])	continue;
    		for (int i=head[u]; ~i; i=edge[tp][i].nex)	{
    			int v = edge[tp][i].v, w = edge[tp][i].w;
    			if (!vis[v] && d[tp][v] > d[tp][u] + w)	{
    				d[tp][v] = d[tp][u] + w;	que.push (Edge (0, v, d[tp][v], 0));
    			}
    		}
    	}
    }
    
    int get_max(void)	{
    	int ret = 0;
    	for (int i=1; i<=n; ++i)	{
    		ret = max (ret, d[0][i] + d[1][i]);
    	}
    	return ret;
    }
    
    int main(void)	{
    	while (scanf ("%d%d%d", &n, &m, &x) == 3)	{
    		init ();
    		for (int u, v, w, i=0; i<m; ++i)	{
    			scanf ("%d%d%d", &u, &v, &w);
    			add_edge (u, v, w);
    		}
    		//SPFA (x, 0);
    		Dijkstra (x, 0);
    		build_re_graph ();
    		//SPFA (x, 1);
    		Dijkstra (x, 1);
    		int ans = get_max ();
    		printf ("%d
    ", ans);
    	}
    
    	return 0;
    }
    

    还有一道类似的题目,是求最大和,其实都是一样的

    POJ 1511 

    //#include <bits/stdc++.h>
    #include <cstdio>
    #include <queue>
    #include <algorithm>
    #include <cstring>
    using namespace std;
    
    typedef long long ll;
    const int N = 1e6 + 5;
    const int E = N;
    const int INF = 0x3f3f3f3f;
    struct Edge	{
    	int u, v, w, nex;
    	Edge() {}
    	Edge(int u, int v, int w, int nex) : u (u), v (v), w (w), nex (nex) {}
    	bool operator < (const Edge &r)	const	{
    		return w > r.w;
    	}
    }edge[2][E];
    int head[N];
    int d[N];
    bool vis[N];
    int n, m, e;
    
    inline int read(void)	{
    	int f = 1, ret = 0;	char ch = getchar ();
    	while (ch > '9' || ch < '0')	{
    		if (ch == '-')	f = -1;
    		ch = getchar ();
    	}
    	while (ch <= '9' && ch >= '0')	{
    		ret = ret * 10 + ch - '0';
    		ch = getchar ();
    	}
    	return ret * f;
    }
    
    void init(void)	{
    	memset (head, -1, sizeof (head));
    	e = 0;
    }
    
    void add_edge(int u, int v, int w)	{
    	edge[0][e] = Edge (u, v, w, head[u]);
    	head[u] = e++;
    }
    
    void build_re_graph(void)	{
    	memset (head, -1, sizeof (head));
    	e = 0;
    	for (int i=0; i<m; ++i)	{
    		edge[1][e] = Edge (edge[0][i].v, edge[0][i].u, edge[0][i].w, head[edge[0][i].v]);
    		head[edge[0][i].v] = e++;
    	}
    }
    
    void SPFA(int s, int tp)	{
    	memset (d, INF, sizeof (d));
    	memset (vis, false, sizeof (vis));
    	d[s] = 0;	vis[s] = true;
    	queue<int> que;	que.push (s);
    	while (!que.empty ())	{
    		int u = que.front ();	que.pop ();
    		vis[u] = false;
    		for (int i=head[u]; ~i; i=edge[tp][i].nex)	{
    			int v = edge[tp][i].v, w = edge[tp][i].w;
    			if (d[v] > d[u] + w)	{
    				d[v] = d[u] + w;
    				if (!vis[v])	{
    					vis[v] = true;	que.push (v);
    				}
    			}
    		}
    	}
    }
    
    ll get_sum(void)	{
    	ll ret = 0;
    	for (int i=1; i<=n; ++i)	{
    		ret += d[i];
    	}
    	return ret;
    }
    
    int main(void)	{
    	int T;	scanf ("%d", &T);
    	while (T--)	{
    		scanf ("%d%d", &n, &m);
    		init ();
    		for (int u, v, w, i=0; i<m; ++i)	{
    			//scanf ("%d%d%d", &u, &v, &w);
    			u = read ();	v = read ();	w = read ();
    			add_edge (u, v, w);
    		}
    		SPFA (1, 0);
    		ll ans = get_sum ();
    		build_re_graph ();
    		SPFA (1, 1);
    		ans += get_sum ();
    		printf ("%lld
    ", ans);
    	}
    
    	return 0;
    }
    

      

    编译人生,运行世界!
  • 相关阅读:
    IDEA安装scala搭建项目环境
    安装配置Maven和创建Java项目
    IDEA 2019.2的安装破解教程
    GroupBy
    C#快速傅立叶变换(Fast Fourier Transform)
    多种方式收费解决方案
    随机数生成算法
    C#生成随机数的三种方法
    统治世界的十大算法,你都了解多少?
    VR和AR技术是什么意思 二者有什么区别详解
  • 原文地址:https://www.cnblogs.com/Running-Time/p/5001609.html
Copyright © 2011-2022 走看看