题目大意:有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; }
时间: 2024-10-12 01:41:22