| 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