AOJ 2249
2015-09-30 23:24
316 查看
优先队列+Dijkstra
因为题目中所给的点的个数多达10000个,而且看得出来要求最短路,但是普通的Dijkstra的效率为O(n^2),这显然是不行的,那么我们可以用优先队列+DIjkstra。题目中说了,要求去掉一些边,使得总花费最少,但是去掉边后不能影响从源点到其他所有点的最短路。那么与普通的相比,就是当dis[v] == dis[u] + r [u] [v]时是cost[v]小还是cost[u]+cost[u][v]小,那么我们在制定有些队列的规则时只要注意先保证最短路,如果长度相同,那么我们就首先取出那个花费少的路,加上就行。边的话因为n比较大,所以我们采用邻接表来存储。
因为题目中所给的点的个数多达10000个,而且看得出来要求最短路,但是普通的Dijkstra的效率为O(n^2),这显然是不行的,那么我们可以用优先队列+DIjkstra。题目中说了,要求去掉一些边,使得总花费最少,但是去掉边后不能影响从源点到其他所有点的最短路。那么与普通的相比,就是当dis[v] == dis[u] + r [u] [v]时是cost[v]小还是cost[u]+cost[u][v]小,那么我们在制定有些队列的规则时只要注意先保证最短路,如果长度相同,那么我们就首先取出那个花费少的路,加上就行。边的话因为n比较大,所以我们采用邻接表来存储。
#include<stdio.h> #include<iostream> #include<string> #include<string.h> #include<algorithm> #include<iomanip> #include<vector> #include<time.h> #include<queue> #include<stack> #include<iterator> #include<math.h> #include<stdlib.h> #include<limits.h> #include<map> #include<set> #include<bitset> //#define ONLINE_JUDGE #define eps 1e-5 #define INF 0x7fffffff #define FOR(i,a) for((i)=0;i<(a);(i)++) #define MEM(a) (memset((a),0,sizeof(a))) #define sfs(a) scanf("%s",a) #define sf(a) scanf("%d",&a) #define sfI(a) scanf("%I64d",&a) #define pf(a) printf("%d\n",a) #define pfI(a) printf("%I64d\n",a) #define pfs(a) printf("%s\n",a) #define sfd(a,b) scanf("%d%d",&a,&b) #define sft(a,b,num) scanf("%d%d%d",&a,&b,&num) #define for1(i,a,b) for(int i=(a);i<b;i++) #define for2(i,a,b) for(int i=(a);i<=b;i++) #define for3(i,a,b)for(int i=(b);i>=a;i--) #define MEM1(a) memset(a,0,sizeof(a)) #define MEM2(a) memset(a,-1,sizeof(a)) #define ll long long const double PI=acos(-1.0); template<class T> T gcd(T a,T b){return b?gcd(b,a%b):a;} template<class T> T lcm(T a,T b){return a/gcd(a,b)*b;} template<class T> inline T Min(T a,T b){return a<b?a:b;} template<class T> inline T Max(T a,T b){return a>b?a:b;} using namespace std; //#pragma comment(linker,"/STACK:1024000000,1024000000") int n,m,x; //#define N 200005 #define M 100010 #define Mod 1000000000 #define p(x,y) make_pair(x,y) const int MAX_len=550; int tot; struct Edge{ int v; int len,cost; }; vector<Edge> G[10010]; struct Node{ int id,len,val; bool operator <(const Node &x)const{ //首先保证最短路,如果长度相同,那么再比较花费,花费少的放在堆顶 return (len == x.len?val>x.val:len>x.len); } }; void Dijsktra(){ int dis[10010]; int vis[10010]; memset(dis,0x3f3f3f3f,sizeof dis); memset(vis,0,sizeof vis); dis[1]=0; priority_queue<Node> q; q.push((Node){1,0,0}); int ans=0; while(!q.empty()){ Node tmp = q.top(); // q.pop(); if(vis[tmp.id]) continue; vis[tmp.id] = 1; ans += tmp.val; for(int i=0;i<(int)G[tmp.id].size();i++){ int v = G[tmp.id][i].v; int len = G[tmp.id][i].len; int cost = G[tmp.id][i].cost; if(!vis[v] && dis[v]>=dis[tmp.id]+len){//注意,我们现在松弛的条件是dis[v]>=dis[tmp.id]+len,有=哦 dis[v] = dis[tmp.id]+len; q.push((Node){v,dis[v],cost}); } } } printf("%d\n",ans); } int main(){ #ifndef ONLINE_JUDGE freopen("in.txt", "r", stdin); // freopen("out.txt", "w", stdout); #endif while(scanf("%d%d",&n,&m)!=EOF && n+m){ for(int i=0;i<=n;i++) G[i].clear(); int u,v,len,cost; for(int i=0;i<m;i++){ scanf("%d%d%d%d",&u,&v,&len,&cost); G[u].push_back((Edge){v,len,cost}); G[v].push_back((Edge){u,len,cost}); } Dijsktra(); } return 0; }
相关文章推荐
- Path Sum II 解答
- 开发环境配置及优化
- 一个简单地C语言程序展示RSA加密原理
- ArtTemplate模板引擎入门
- [置顶] 细谈Struts2框架(一) Struts2框架之原理
- C++——Static变量初始化
- jquery一些技巧总结
- The State of Front-End Tooling – 2015
- 细谈Struts2框架(四)Struts2框架之标签库
- 谈谈jquery性能优化的常用策略
- 多线程中的同步
- RAW碰到的问题与功能的测试
- ORACLE 11g用户权限管理随笔精髓
- 2015年英语学习——9月
- [经济生活基本知识]社会主义市场经济
- ZOJ 2932
- c# panel里面嵌入窗体
- JavaWeb 创建省市级关联菜单
- 《编程之美》--字符串移位包含的问题
- 前端自动化:谈谈grunt和gulp的区别