Time Limit: 8000MS | Memory Limit: 262144K | |
Total Submissions: 21615 | Accepted: 7089 |
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的最短路之和。
分析:很明显地,利用spfa or dijkstra+heap,顺着存边求一次最短路,然后把边反向求一次最短路,然后求和即可。如果这个题目用vector存图的话,那么很容易卡时间,比如存图我用两个临接表直接存储就TLE了,后来改成一个临接表才过的。然而这样子还是卡时间,还可以继续优化。题意很清晰,边的数量是1000000,那么我们可以直接用结构体数组把边存下来,这样子在数组上操作,就不会很费时了。具体见代码:
题目链接:http://poj.org/problem?id=1511
代码清单:
vector实现(时间复杂度高):
#include<queue> #include<vector> #include<stdio.h> #include<string.h> #include<iostream> #include<algorithm> using namespace std; typedef long long ll; const int maxn=1000000+5; const int max_dis=1e9 + 5; struct Edge{ int to,dis; Edge(int to,int dis){ this -> to = to; this -> dis = dis; } }; struct edge{ int from,to,dis; }g[maxn]; int T; int n,Q; int a,b,c; int d[maxn]; bool vis[maxn]; typedef pair<int,int>P; vector<Edge>graph[maxn]; void Clear(){ for(int i=1;i<=n;i++){ graph[i].clear(); } } void input(){ scanf("%d%d",&n,&Q); Clear(); for(int i=0;i<Q;i++){ scanf("%d%d%d",&g[i].from,&g[i].to,&g[i].dis); graph[g[i].from].push_back(Edge(g[i].to,g[i].dis)); } } ll dijkstra(){ fill(d+1,d+1+n,max_dis); priority_queue<P,vector<P>,greater<P> >q; while(q.size()) q.pop(); d[1]=0; q.push(P(0,1)); while(q.size()){ P p=q.top(); q.pop(); int v=p.second; if(d[v]<p.first) continue; for(int i=0;i<graph[v].size();i++){ Edge& e=graph[v][i]; if(d[e.to]>d[v]+e.dis){ d[e.to]=d[v]+e.dis; q.push(P(d[e.to],e.to)); } } } ll ret=0; for(int i=1;i<=n;i++) ret+=d[i]; return ret; } ll spfa(){ memset(vis,false,sizeof(vis)); fill(d+1,d+1+n,max_dis); queue<int>q; while(!q.empty()) q.pop(); d[1]=0; vis[1]=true; q.push(1); while(!q.empty()){ int p=q.front(); q.pop(); vis[p]=0; for(int i=0;i<graph[p].size();i++){ Edge& e=graph[p][i]; if(d[e.to]>d[p]+e.dis){ d[e.to]=d[p]+e.dis; if(!vis[e.to]){ vis[e.to]=true; q.push(e.to); } } } } ll ret=0; for(int i=1;i<=n;i++) ret+=d[i]; return ret; } void dijkstra_solve(){ ll ans=dijkstra(); Clear(); for(int i=0;i<Q;i++){ graph[g[i].to].push_back(Edge(g[i].from,g[i].dis)); } ans+=dijkstra(); printf("%I64d\n",ans); } void spfa_solve(){ ll ans=spfa(); Clear(); for(int i=0;i<Q;i++){ graph[g[i].to].push_back(Edge(g[i].from,g[i].dis)); } ans+=spfa(); printf("%I64d\n",ans); } int main(){ scanf("%d",&T); while(T--){ input(); dijkstra_solve(); //spfa_solve(); }return 0; }
#include<queue> #include<vector> #include<stdio.h> #include<string.h> #include<iostream> #include<algorithm> using namespace std; typedef long long ll; const int maxn=1000000+5; const int max_dis=1e9 + 5; struct Edge{int to,dis,next;}graph[maxn]; struct edge{int from,to,dis;}g[maxn]; int T; int n,Q; int num; int d[maxn]; bool vis[maxn]; int head[maxn]; typedef pair<int,int>P; void Clear(){ num=0; memset(head,-1,sizeof(head)); memset(graph,0,sizeof(graph)); } void add(int u,int v,int dis){ graph[num].to=v; graph[num].dis=dis; graph[num].next=head[u]; head[u]=num++; } void input(){ scanf("%d%d",&n,&Q); Clear(); for(int i=0;i<Q;i++){ scanf("%d%d%d",&g[i].from,&g[i].to,&g[i].dis); add(g[i].from,g[i].to,g[i].dis); } } ll dijkstra(){ fill(d+1,d+1+n,max_dis); priority_queue<P,vector<P>,greater<P> >q; while(q.size()) q.pop(); d[1]=0; q.push(P(0,1)); while(q.size()){ P p=q.top(); q.pop(); int v=p.second; if(d[v]<p.first) continue; for(int k=head[v];k>-1;k=graph[k].next){ if(d[graph[k].to]>d[v]+graph[k].dis){ d[graph[k].to]=d[v]+graph[k].dis; q.push(P(d[graph[k].to],graph[k].to)); } } } ll ret=0; for(int i=1;i<=n;i++) ret+=d[i]; return ret; } ll spfa(){ memset(vis,false,sizeof(vis)); fill(d+1,d+1+n,max_dis); queue<int>q; while(!q.empty()) q.pop(); d[1]=0; vis[1]=true; q.push(1); while(!q.empty()){ int v=q.front(); q.pop(); vis[v]=0; for(int k=head[v];k>-1;k=graph[k].next){ if(d[graph[k].to]>d[v]+graph[k].dis){ d[graph[k].to]=d[v]+graph[k].dis; if(!vis[graph[k].to]){ vis[graph[k].to]=true; q.push(graph[k].to); } } } } ll ret=0; for(int i=1;i<=n;i++) ret+=d[i]; return ret; } void dijkstra_solve(){ ll ans=dijkstra(); Clear(); for(int i=0;i<Q;i++){ add(g[i].to,g[i].from,g[i].dis); } ans+=dijkstra(); printf("%I64d\n",ans); } void spfa_solve(){ ll ans=spfa(); Clear(); for(int i=0;i<Q;i++){ add(g[i].to,g[i].from,g[i].dis); } ans+=spfa(); printf("%I64d\n",ans); } int main(){ scanf("%d",&T); while(T--){ input(); //dijkstra_solve(); spfa_solve(); }return 0; }
版权声明:本文为博主原创文章,未经博主允许不得转载。
POJ_1511_Invitation Cards(最短路)
原文地址:http://blog.csdn.net/jhgkjhg_ugtdk77/article/details/47095345