标签:
Time Limit: 8000MS | Memory Limit: 262144K | |
Total Submissions: 23357 | Accepted: 7675 |
Description
Input
Output
Sample Input
2 2 2 1 2 13 2 1 33 4 6 1 2 10 2 1 60 1 3 20 3 4 10 2 4 5 4 1 50
Sample Output
46 210
题意:求1号结点到其余各结点路径之和与其余各结点到1号结点之和的和。
思路:求其余各结点到1号结点的路径时可将有向边反向,转化为求1号结点到其余各结点的路径之和。注意:该题目的数据量较大,用动态邻接表存储会RE。
对比了一下 dijkstra 与 spfa算法。
/* dijkstra 1511 Accepted 39744K 1907MS G++ */ #include"cstdio" #include"queue" #include"vector" using namespace std; const int MAXN=1000005; const int INF=0x3fffffff; typedef long long LL; typedef pair<int,int> P; struct Edge{ int to,cost,next; }es[2][MAXN]; int V,E; int head[2][MAXN]; LL d[MAXN]; void add_edge(int u,int v,int cost,int type) { es[type][E].to=v; es[type][E].cost=cost; es[type][E].next=head[type][u]; head[type][u]=E; } LL dijkstra(int s,int type) { for(int i=1;i<=V;i++) d[i]=INF; priority_queue<P,vector<P>,greater<P> > que; d[s]=0,que.push(P(0,s)); while(!que.empty()) { P p=que.top();que.pop(); int v=p.second; if(d[v]<p.first) continue; for(int i=head[type][v];i!=-1;i=es[type][i].next) { Edge e=es[type][i]; if(d[e.to]>d[v]+e.cost) { d[e.to]=d[v]+e.cost; que.push(P(d[e.to],e.to)); } } } LL ans=0; for(int i=1;i<=V;i++) ans+=d[i]; return ans; } int main() { int T; scanf("%d",&T); for(int cas=1;cas<=T;cas++) { int P,Q; scanf("%d%d",&P,&Q); V=P,E=0; for(int i=1;i<=V;i++) head[0][i]=head[1][i]=-1; for(int i=0;i<Q;i++) { int u,v,co; scanf("%d%d%d",&u,&v,&co); add_edge(u,v,co,0); add_edge(v,u,co,1); E++; } LL res=0; res+=dijkstra(1,0); res+=dijkstra(1,1); printf("%I64d\n",res); } return 0; }
/* spfa 1511 Accepted 43676K 1875MS G++ */ #include"cstdio" #include"queue" using namespace std; const int MAXN=1000005; const int INF=0x3fffffff; typedef long long LL; struct Edge{ int to,cost,next; }es[2][MAXN]; int head[2][MAXN]; int V,E; LL d[MAXN]; int vis[MAXN]; LL spfa(int s,int type) { for(int i=1;i<=V;i++) { d[i]=INF; vis[i]=0; } queue<int> que; vis[s]=1,d[s]=0,que.push(s); while(!que.empty()) { int v=que.front();que.pop(); vis[v]=0; for(int i=head[type][v];i!=-1;i=es[type][i].next) { Edge e=es[type][i]; if(d[e.to]>d[v]+e.cost) { d[e.to]=d[v]+e.cost; if(!vis[e.to]) { que.push(e.to); vis[e.to]=1; } } } } LL ans=0; for(int i=1;i<=V;i++) ans+=d[i]; return ans; } int main() { int T; scanf("%d",&T); for(int cas=1;cas<=T;cas++) { int P,Q; scanf("%d%d",&P,&Q); V=P,E=0; for(int i=1;i<=V;i++) head[0][i]=head[1][i]=-1; for(int i=0;i<Q;i++) { int u,v,co; scanf("%d%d%d",&u,&v,&co); es[0][E].to=v,es[0][E].cost=co,es[0][E].next=head[0][u],head[0][u]=E; es[1][E].to=u,es[1][E].cost=co,es[1][E].next=head[1][v],head[1][v]=E; E++; } LL res=0; res+=spfa(1,0); res+=spfa(1,1); printf("%I64d\n",res); } return 0; }
堆优化dijkstra 算法的复杂度为 |E|*log(|V|) ,优势在于处理稀疏图。
标签:
原文地址:http://www.cnblogs.com/program-ccc/p/5154312.html