题目大意:有n个站,和m条单向边,每条边有乘车价值,保证汽车能开回来。有n-1个学生从1出发,分别到n-1个不同的点,然后回来。求最少的总价值。
解题思路:最短路,求回来的最少价值其实可以建立反向图,然后跑最短路即可。一共两遍最短路,我用堆优化Dijkstra算法,时间复杂度$O(m\log n)$。
注意long long。
pbds大法好!
C++ Code:
#include<ext/pb_ds/priority_queue.hpp>
#include<cstdio>
#include<cstring>
#define N (1000000+10)
#define C c=getchar()
int head[2][N<<1],nxt[2][N<<1],to[2][N<<1],n,m,cnt;
long long dis[2][N<<1],ans[N];
inline int readint(){
char C;
while(!isdigit(c))C;
int p=0;
while(isdigit(c))p=(p<<3)+(p<<1)+(c^'0'),C;
return p;
}
struct heapnode{
long long d;int u;
bool operator <(const heapnode& rhs)const{return d>rhs.d;}
};
__gnu_pbds::priority_queue<heapnode>Q;
void dijkstra(int p){
memset(ans,0x3f,sizeof(ans));
ans[1]=0;
Q.push((heapnode){0,1});
while(!Q.empty()){
heapnode x=Q.top();Q.pop();
int u=x.u;
if(ans[u]!=x.d)continue;
for(int i=head[p][u];i;i=nxt[p][i]){
int v=to[p][i];
if(ans[v]>ans[u]+dis[p][i]){
ans[v]=ans[u]+dis[p][i];
Q.push((heapnode){ans[v],v});
}
}
}
}
int main(){
n=readint(),m=readint();
cnt=0;
while(m--){
int x=readint(),y=readint(),d=readint();
++cnt;
to[0][cnt]=y;
dis[0][cnt]=d;
nxt[0][cnt]=head[0][x];
head[0][x]=cnt;
to[1][cnt]=x;
dis[1][cnt]=d;
nxt[1][cnt]=head[1][y];
head[1][y]=cnt;
}
long long Answer=0;
for(int i=0;i<2;++i){
dijkstra(i);
for(int j=2;j<=n;++j)Answer+=ans[j];
}
printf("%lld\n",Answer);
return 0;
}