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;
    }
    

      

    编译人生,运行世界!
  • 相关阅读:
    服务器响应状态码
    细说同域-同父域-跨域
    细说Ajax跨域
    为SQL缓存通知启用数据库
    使用PATINDEX()判断含有[A-Z]、[a-z]、[0-9]之外的字符
    记一次SQLServer的分页优化兼谈谈使用Row_Number()分页存在的问题
    谈谈如何在面试中发掘程序猿的核心竞争力
    “属性”与“特性”区别
    【转】安卓手机无法安装软件的原因总结
    【转】自学android半年,已从.net转型成android程序员
  • 原文地址:https://www.cnblogs.com/Running-Time/p/5001609.html
Copyright © 2011-2022 走看看