| 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