题意:
给你一个图,其中包含n个点,m条边。使的每个点到达1号点的路程最短。求出修建这些边的最小长度。
题解:
最短路
代码如下:
#include<bits/stdc++.h>
using namespace std;
const int maxn=1e4+5,INF=2e9+7;
int n,m,ans,Dis[maxn],Path[maxn];
bool vis[maxn];
struct node{
int id,dis;
bool operator<(const node &rs)const{
return dis>rs.dis;
}
};
vector<node>vec[maxn];
void dij(){
int i,lenV,pre,tmp;
node now,next;
priority_queue<node>qu;
for (i=1;i<=n;i++)Dis[i]=INF,Path[i]=-1,vis[i]=0;
Dis[1]=0;qu.push({1,0});
while(!qu.empty()){
now=qu.top();qu.pop();
if(Dis[now.id]<now.dis)continue;
lenV=vec[now.id].size();
for (i=0;i<lenV;i++){
next=vec[now.id][i];
if(Dis[next.id]>now.dis+next.dis){
Dis[next.id]=now.dis+next.dis;
Path[next.id]=now.id;
qu.push({next.id,Dis[next.id]});
}
else if(Dis[next.id]==now.dis+next.dis){
pre=Path[next.id];
if(pre!=-1){
tmp=Dis[next.id]-Dis[pre];
if(next.dis<tmp)Path[next.id]=now.id;
}
}
}
}
for (i=2;i<=n;i++){
if(vis[i])continue;
tmp=i;
while(Path[tmp]!=-1&&(!vis[tmp])){
pre=Path[tmp];
ans+=Dis[tmp]-Dis[pre];
vis[tmp]=true;
if(vis[pre])break;
tmp=pre;
}
}
printf("%d\n",ans);
}
int main(){
int i,a,b,c;
while(scanf("%d%d",&n,&m)!=EOF){
ans=0;
for(i=0;i<=10000;i++)vec[i].clear();
while(m--){
scanf("%d%d%d",&a,&b,&c);
vec[a].push_back({b,c});
vec[b].push_back({a,c});
}
dij();
}
return 0;
}