POJ 1511 Invitation Cards (ZOJ 2008) 使用优先队列的dijkstra
传送门:
http://poj.org/problem?id=1511
http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemId=1008
题目大意:
给定p个点,还有他们的边q,(有向图)求从结点1出发到所有结点和所有结点到1的最短路径之和。
其中1 <= P,Q <= 1000000
思路:
和上次 POJ 3268 Silver Cow Party 一样,有向图倒着建立就把从所有结点到1的最短路径改为了从1到所有,那么只需两次dijkstra即可。
还有就是数据量大,要用优先队列的dijkstra,堆优化的更好。
嗯,第一次写这个,参考了别人的。
code1:2014/1/1更新。。。
今天自己写的------
直接用数组模拟链表快了好多,zoj排名挺靠前面的,嘻嘻,不过poj又被虐。。
#include<cstdio> #include<cstring> #include<queue> using namespace std; const int MAXN=1000000+10; bool vis[MAXN]; int head[2][MAXN]; int n,m; long long ans; struct edge { int to; int cost; int next; }e[2][MAXN]; struct node { int from; int cost; node(int f,int c){from=f;cost=c;} bool operator < (const node& b)const { return cost > b.cost; } }; int len; void insert(int from,int to,int cost) { e[0][len].to=to; e[1][len].to=from; e[0][len].cost=e[1][len].cost=cost; e[0][len].next = head[0][ from ]; e[1][len].next = head[1][ to ]; head[0][from]=len; head[1][to]=len; len++; } void dijkstra(int kind) { memset(vis,0,sizeof(vis)); priority_queue<node> q; q.push(node(1,0)); int num=0; while(!q.empty()) { node cur=q.top(); q.pop(); if(vis[cur.from]==true) continue; vis[cur.from]=true; ans+=cur.cost; num++; if(num==n) break; //这里写得真纠结- -||| for(int ne=head[kind][cur.from];ne!=-1;ne=e[kind][ ne ].next) { if(!vis[e[kind][ ne ].to]) q.push(node(e[kind][ ne ].to,e[kind][ ne ].cost+cur.cost)); } } } int main() { int T; scanf("%d",&T); int from,to,cost; while(T--) { len=0; memset(head,-1,sizeof(head)); scanf("%d%d",&n,&m); for(int i=0;i<m;i++) { scanf("%d%d%d",&from,&to,&cost); insert(from,to,cost); } ans=0; dijkstra(0); dijkstra(1); printf("%lld\n",ans); } return 0; }
code 2:
2013/12/31第一次写,基本上是模仿别人的
#include<cstdio> #include<cstring> #include<queue> using namespace std; const int MAXN=1000000+10; long long ans; bool vis[MAXN]; int n,m; struct edge { int to,cost; edge* next; edge(){next=NULL;} }*e[2][MAXN]; struct node { int cost,id; bool operator < (const node& b) const { return cost>b.cost; } node(int i,int c){ cost =c;id=i;} }; inline void addedge(int from,int to,int cost) { edge *p=new edge; edge *q=new edge; p->next=e[0][from]; q->next=e[1][to]; p->to=to; q->to=from; p->cost=q->cost=cost; e[0][from]=p; e[1][to]=q; } void dijkstra(int kind) { memset(vis,0,sizeof(vis)); priority_queue<node> q; int num=0; node cur(1,0); q.push(cur); while(!q.empty()) { cur=q.top(); q.pop(); if(vis[cur.id]==true) continue; vis[cur.id]=true; ans+=cur.cost; num++; if(num==n) break; for(edge *p=e[kind][cur.id];p!=NULL;p=p->next) { if(vis[p->to]==false) { node temp(p->to,p->cost+cur.cost); q.push(temp); } } } } int main() { int T; scanf("%d",&T); while(T--) { memset(e,NULL,sizeof(e)); scanf("%d%d",&n,&m); for(int i=0;i<m;i++) { int from,to,cost; scanf("%d%d%d",&from,&to,&cost); addedge(from,to,cost); } ans=0; dijkstra(0); dijkstra(1); printf("%lld\n",ans); } return 0; }
新 blog : www.hrwhisper.me