poj 1511 优先队列优化dijkstra *

题意:两遍最短路

链接:点我

注意结果用long long

  1 #include<cstdio>
  2 #include<iostream>
  3 #include<algorithm>
  4 #include<cstring>
  5 #include<cmath>
  6 #include<queue>
  7 #include<map>
  8 using namespace std;
  9 #define MOD 1000000007
 10 #define pb(a) push_back(a)
 11 const int INF=0x3f3f3f3f;
 12 const double eps=1e-5;
 13 typedef long long ll;
 14 #define cl(a) memset(a,0,sizeof(a))
 15 #define ts printf("*****\n");
 16 const int MAXN=1000005;
 17 int p[MAXN],q[MAXN],w[MAXN];
 18 int n,m,tt,cnt;
 19 /*
 20 * 使用优先队列优化Dijkstra算法
 21 * 复杂度O(ElogE)
 22 * 注意对vector<Edge>E[MAXN]进行初始化后加边
 23 */
 24 struct qnode
 25 {
 26 int v;
 27 int c;
 28 qnode(int _v=0,int _c=0):v(_v),c(_c){}
 29 bool operator <(const qnode &r)const
 30 {
 31 return c>r.c;
 32 }
 33 };
 34 struct Edge
 35 {
 36 int v,cost;
 37 Edge(int _v=0,int _cost=0):v(_v),cost(_cost){}
 38 };
 39 vector<Edge>E[MAXN];
 40 bool vis[MAXN];
 41 int dist[MAXN];
 42 void Dijkstra(int n,int start)//点的编号从1开始
 43 {
 44 memset(vis,false,sizeof(vis));
 45 for(int i=1;i<=n;i++)dist[i]=INF;
 46 priority_queue<qnode>que;
 47 while(!que.empty())que.pop();
 48 dist[start]=0;
 49 que.push(qnode(start,0));
 50 qnode tmp;
 51 while(!que.empty())
 52 {
 53 tmp=que.top();
 54 que.pop();
 55 int u=tmp.v;
 56 if(vis[u])continue;
 57 vis[u]=true;
 58 for(int i=0;i<E[u].size();i++)
 59 {
 60 int v=E[tmp.v][i].v;
 61 int cost=E[u][i].cost;
 62 if(!vis[v]&&dist[v]>dist[u]+cost)
 63 {
 64 dist[v]=dist[u]+cost;
 65 que.push(qnode(v,dist[v]));
 66 }
 67 }
 68 }
 69 }
 70 void addedge(int u,int v,int w)
 71 {
 72 E[u].push_back(Edge(v,w));
 73 }
 74 int main()
 75 {
 76     int i,j,k;
 77     #ifndef ONLINE_JUDGE
 78     freopen("1.in","r",stdin);
 79     #endif
 80     scanf("%d",&tt);
 81     while(tt--)
 82     {
 83         scanf("%d%d",&n,&m);
 84         for(i=0;i<=n;i++)    E[i].clear();
 85         for(i=0;i<m;i++)
 86         {
 87             scanf("%d%d%d",&p[i],&q[i],&w[i]);
 88             addedge(p[i],q[i],w[i]);
 89         }
 90         Dijkstra(n,1);
 91         ll sum=0;
 92         for(i=2;i<=n;i++)
 93         {
 94             sum+=dist[i];
 95         }
 96         for(i=0;i<=n;i++)    E[i].clear();
 97         for(i=0;i<m;i++)    addedge(q[i],p[i],w[i]);
 98         Dijkstra(n,1);
 99         for(i=2;i<=n;i++)
100         {
101             sum+=dist[i];
102         }
103         printf("%I64d\n",sum);
104     }
105 }
时间: 2024-11-07 15:14:13

poj 1511 优先队列优化dijkstra *的相关文章

POJ 1511 Invitation Cards(dijkstra+优先队列)

题目链接:http://poj.org/problem?id=1511 题目大意:给你n个点,m条边(1<=n<=m<=1e6),每条边长度不超过1e9.问你从起点到各个点以及从各个点到起点的最小路程总和. 解题思路:这里用了优先队列优化的dijkstra复杂度mlogn,从起点到个点最短路径直接算就好了,算各个点到起点的最短路径,只要把边的方向反一下,再算一次从起点到个点最短路径就好了. 1 #include<iostream> 2 #include<cstdio&g

数组优化 Dijkstra 最短路

//============================================================================// Name : POJ.cpp// Author : // Version :// Copyright : Your copyright notice// Description : Hello World in C++, Ansi-style//==============================================

POJ 3013 Big Christmas Tree(最短路Dijkstra+优先队列优化,SPFA)

POJ 3013 Big Christmas Tree(最短路Dijkstra+优先队列优化,SPFA) ACM 题目地址:POJ 3013 题意: 圣诞树是由n个节点和e个边构成的,点编号1-n,树根为编号1,选择一些边,使得所有节点构成一棵树,选择边的代价是(子孙的点的重量)×(这条边的价值).求代价最小多少. 分析: 单看每个点被计算过的代价,很明显就是从根到节点的边的价值.所以这是个简单的单源最短路问题. 不过坑点还是很多的. 点的数量高达5w个,用矩阵存不行,只能用边存. 还有路径和结

poj 3013 Big Christmas Tree (dij+优先队列优化 求最短路)

模板 题意:给你一个图,1总是为根,每个边有单位价值,每个点有权重. 每条边的价值 = sum(后继节点权重)*边的单位价值. 求树的最小价值,即构成一棵树的n-1条边的最小价值. 算法: 1.因为每个边的价值都要乘以后来访问的节点的权重,而走到后来访问的点必经过这条边. 实际上总价值就是  到每个点的最短路径*这个点的权重. 2.但是这个题 数据量真的太大了,50000个点,50000条边. 写普通的dij算法tle. 必须加优先队列优化- - 据说spfa也能过,但是spfa算法不稳定- -

Poj 1151 Invitation Cards dijkstra 堆优化

很裸的最短路,不过节点数和边数都是1e6,直接dij肯定是不行了,稀疏图用heap优化一下就好 o(╯□╰)o注意STL里面的优先队列是优先级大的(值大的)在前面的,一开始没注意WA了好几发,哎,太粗心了 #include <cstdio> #include <cstring> #include <cmath> #include <algorithm> #include <climits> #include <string> #inc

HDU - 3790 最短路径问题(Dijkstra+优先队列优化)

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=3790 题意:中文题(边被赋予两种属性,一种是路径,一种是花费),然后略.(逃...... 今天看了卿学姐的视频,初尝SPFA和Dijkstra. 一个是用队列优化,一个是用优先队列优化.这道题目用这两种方法都可以. dijkstra算法思想(贪心):从距离起点最近的点开始,从这个点遍历一遍它周围的点,进行松弛操作,直到最终点. 整个的算法思想就是贪心,每次都给它形成最短路. 这道题目值得注意的是预处

地铁 Dijkstra(优先队列优化) 湖南省第五届省赛

传送门:地铁 思路:拆点,最短路:拆点比较复杂,所以对边进行最短路,spfa会tle,所以改用Dijkstra(优先队列优化) 模板 /************************************************************** Problem: User: youmi Language: C++ Result: Accepted Time: Memory: *****************************************************

poj 1511 Dijkstra的另一种用法---求其他点到源点的最短路

传送门:http://poj.org/problem?id=1511 题目其实到现在我都没读懂,到底是哪里看出来的,ans是源点到各个点最短路的和外加各个点到源点的最短路的和,不过重要的是学到dijkstra的另一种用法--求各个点到源点的距离,原理不难理解,就是把dijkstra求单源最短路径的过程逆过来: 1.取源点加入S集合,设其余点在T集合 2.找到达源点的最小边,将该边连的点加入S,更新T到S的各个点的最短路径,取最短的边,继续2的过程 而dijastra求单源最短路径的过程 1.取源

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