51-nod(1443)(最短路)
解题思路:最短路+记录前驱和,刚开始一直以为是最短路+MST,结果发现,因为无向图的原因,有些边权很小的边再最短路处理后可能这条边也符合某两个点的最短路径,所以我们觉得这条边也是可以在MST处理中使用的,然而,发现选了这条边后,会导致剩下的点因为选定了不该选的边,因为MST中每条边的选定会确定两个点,所以,在计算最短路的时候记录最小前驱就可以了:2 3 50,2 5 40 ,5 3 10,3的最小前驱为10。。。;
代码
#include<iostream> #include<algorithm> #include<cstdio> #include<cstring> #include<queue> #include<vector> #define ll long long #define maxn 1000050 #define inf 1e15 using namespace std; struct Edge { int to; int next; int w; }edge[maxn]; struct node { int num; int dist; node(int _num,int _dist):num(_num),dist(_dist){} friend bool operator<(node a,node b) { return a.dist>b.dist; } }; int head[maxn]; int cnt; int pre[maxn]; ll dist[maxn]; int f[maxn]; int n,m; void add(int u,int v,int w) { edge[cnt].next=head[u]; edge[cnt].w=w; edge[cnt].to=v; head[u]=cnt++; } void dij(int x) { priority_queue<node>que; for(int i=1;i<=n;i++) dist[i]=inf; dist[x]=0; que.push(node(x,0)); while(!que.empty()) { //cout<<"x"<<endl; node u=que.top(); que.pop(); int now=u.num; for(int i=head[now];i!=-1;i=edge[i].next) { int v=edge[i].to; if(dist[v]>dist[now]+edge[i].w) { dist[v]=dist[now]+edge[i].w; que.push(node(v,dist[v])); pre[v]=edge[i].w; } if(dist[v]==dist[now]+edge[i].w) { pre[v]=min(pre[v],edge[i].w); } } } } int main() { int x,y,w; int e; memset(pre,0,sizeof(pre)); scanf("%d%d",&n,&m); for(int i=1;i<=n;i++) f[i]=i; memset(head,-1,sizeof(head)); for(int i=1;i<=m;i++) { scanf("%d%d%d",&x,&y,&w); add(x,y,w); add(y,x,w); } scanf("%d",&e); dij(e); ll as=0; for(int i=1;i<=n;i++) as+=pre[i]; printf("%lld\n",as); }