P1342 请柬
最近一直在做最短路......所以今天就再做一道最短路吧。。。。
题目描述
在电视时代,没有多少人观看戏剧表演。Malidinesia古董喜剧演员意识到这一事实,他们想宣传剧院,尤其是古色古香的喜剧片。他们已经打印请帖和所有必要的信息和计划。许多学生被雇来分发这些请柬。每个学生志愿者被指定一个确切的公共汽车站,他或她将留在那里一整天,邀请人们参与。
这里的公交系统是非常特殊的:所有的线路都是单向的,连接两个站点。公共汽车离开起始点,到达目的地之后又空车返回起始点。学生每天早上从总部出发,乘公交车到一个预定的站点邀请乘客。每个站点都被安排了一名学生。在一天结束的时候,所有的学生都回到总部。现在需要知道的是,学生所需的公交费用的总和最小是多少。
输入输出格式
输入格式:
第1行有两个整数n、m(1<=n,m<=1000000),n是站点的个数,m是线路的个数。
然后有m行,每行描述一个线路,包括3个整数,起始点,目的地和价格。
总部在第1个站点,价钱都是整数,且小于1000000000。
输出格式:
输出一行,表示最小费用。
输入输出样例
4 6
1 2 10
2 1 60
1 3 20
3 4 10
2 4 5
4 1 50
210
说明
【注意】
此题数据规模较大,需要使用较为高效的算法,此题不设小规模数据分数。
解析:
首先第一眼我们就能看到说明,,,一看到高效算法,我就想起SPFA,,,
SPFA当年是多么地风光,如今又是多么地落魄。。。所以这题是肯定要Dijkstra+堆优化的。。。
下面我们看一下这个题:
由于是从总部到各点,再从各点回到总部,所以开两个邻接表,一次装去时的,一次去回来时的。
所以!!!(敲黑板划重点啦)
这个题的本质就是求两次单源最短路的和
所以我们只需要跑两遍Dijkstra就完事了
价格小于1000000000,显然是要用long long的。
最后,一定要加读入优化啊!!!(不快读会T)
下面给出AC代码和原题链接:
1 #include<bits/stdc++.h> 2 #define inf 336860180 3 using namespace std; 4 long long total2,ans,n,m,x,y,v[1000010],w[1000001],nxt[1010001],head[1010001],v2[1000001],w2[1000010],nxt2[1010001],head2[1010001],minn,dist[1010001],t,f,total,b1,b2,b3; 5 bool pd[1000010]; 6 typedef pair<long long,long long>P; 7 long long read() 8 { 9 int f=1;x=0;char s=getchar(); 10 while(s<'0'||s>'9'){if(s=='-')f=-1;s=getchar();} 11 while(s>='0'&&s<='9'){x=x*10+s-'0';s=getchar();} 12 return x*=f; 13 } 14 void add(long long a,long long b,long long c) 15 { 16 total++; 17 v[total]=b; 18 w[total]=c; 19 nxt[total]=head[a]; 20 head[a]=total; 21 return; 22 } 23 void add2(long long a,long long b,long long c) 24 { 25 total2++; 26 v2[total2]=b; 27 w2[total2]=c; 28 nxt2[total2]=head2[a]; 29 head2[a]=total2; 30 return; 31 } 32 int main() 33 { 34 priority_queue<P,vector<P>,greater<P> >q; 35 memset(head,-1,sizeof(head)); 36 memset(head2,-1,sizeof(head2)); 37 memset(dist,20,sizeof(dist)); 38 cin>>n>>m; 39 for(int i=1;i<=m;i++) 40 { 41 b1=read();b2=read();b3=read(); 42 add(b1,b2,b3); 43 add2(b2,b1,b3); 44 } 45 dist[1]=0; 46 q.push(P(0,1)); 47 while(q.size()) 48 { 49 long long tmp=q.top().second; 50 q.pop(); 51 if(pd[tmp])continue; 52 pd[tmp]=1; 53 for(int i=head[tmp];i!=-1;i=nxt[i]) 54 { 55 if(dist[v[i]]>dist[tmp]+w[i]) 56 { 57 dist[v[i]]=dist[tmp]+w[i]; 58 q.push(P(dist[v[i]],v[i])); 59 } 60 } 61 } 62 for(int i=2;i<=n;i++)ans+=dist[i]; 63 memset(dist,20,sizeof(dist)); 64 dist[1]=0; 65 q.push(P(0,1)); 66 memset(pd,0,sizeof(pd)); 67 while(q.size()) 68 { 69 long long tmp=q.top().second; 70 q.pop(); 71 if(pd[tmp])continue; 72 pd[tmp]=1; 73 for(int i=head2[tmp];i!=-1;i=nxt2[i]) 74 { 75 if(dist[v2[i]]>dist[tmp]+w2[i]) 76 { 77 dist[v2[i]]=dist[tmp]+w2[i]; 78 q.push(P(dist[v2[i]],v2[i])); 79 } 80 } 81 } 82 for(int i=2;i<=n;i++)ans+=dist[i]; 83 cout<<ans; 84 return 0; 85 }
原题:https://www.luogu.org/problemnew/show/P1342
还有一道和此题完全相同且数据量更小的题:https://www.luogu.org/problemnew/show/P1629;
这么好的题解,不关注+素质三连一波吗???