非常明显的最短路径题目,只不过该题是求路径上被损坏的权重之和
这里可以使用floyd(该题数据量较小)或者是dijkstra进行解答
这里我们选择使用邻接矩阵进行存储图(方便后续)
可以将未被损坏的边的权值都赋为0(不会影响最短路径的求取)
而损坏的边的权值都赋值为应有的权值
在上述基础上进行最短路径值的求取即可
下面给出floyd的代码(dijkstra思路一致)
#include<bits/stdc++.h> using namespace std; const int MAX=100010,inf=0x3f3f3f3f; int n,m,d,A,B; int edges[105][105]; bool use[105][105]; int main(){ memset(use,true,sizeof(use)); cin>>n; cin>>m; for(int i=1;i<=n;i++){ for(int j=1;j<=n;j++){ edges[i][j]=edges[j][i]=inf; } } for(int i=1;i<=m;i++){ int u,v,w; cin>>u>>v>>w; edges[u][v]=w; edges[v][u]=w; } cin>>d; for(int i=1;i<=d;i++){ int u,v,w; cin>>u>>v; use[u][v]=use[v][u]=false;//标记被损坏的边 } for(int i=1;i<=n;i++){ for(int j=1;j<=n;j++){ if(use[i][j]&&edges[i][j]!=inf){ edges[i][j]=0;//赋值未被损坏的边为0 } } } for(int k=1;k<=n;k++){ for(int i=1;i<=n;i++){ for(int j=1;j<=n;j++){ if(edges[i][k]+edges[k][j]<edges[i][j]){ edges[j][i]=edges[i][j]=edges[i][k]+edges[k][j]; } } } } cin>>A>>B; cout<<edges[A][B]<<endl; return 0; }
第二思路较第一思路比较复杂(主要是一开始没想好使用了邻接表存储)
这里使用了堆优化的dijkstra求出了起点到终点的最短路径以及最短路径的大小
再使用一个二维数组存储被损坏的边的权值,再顺着最短路径进行计算即可
#include<bits/stdc++.h> //#define int long long #define pii pair<int,int> using namespace std; const int MAX=100010,inf=0x3f3f3f3f; int n,m,d,A,B; int dis[MAX],flag[MAX]; vector<pii>mapp[MAX]; vector<pii>destory; int path[MAX];//存储路径上每一个点的前一个点 void dijkstra(){ for(int i=0;i<MAX;i++)dis[i]=inf,flag[i]=0,path[i]=-1;//初始化 for(int i=0;i<mapp[A].size();i++){ if(mapp[A][i].second<inf){ path[mapp[A][i].first]=A; } } dis[A]=0; priority_queue<pii,vector<pii>,greater<pii> >p; p.push({0,A}); while(!p.empty()){ int u=p.top().second; p.pop(); if(flag[u])continue; flag[u]=true; for(int i=0;i<mapp[u].size();i++){ int cost=mapp[u][i].second,v=mapp[u][i].first; if(dis[v]>cost+dis[u]){ path[v]=u; dis[v]=dis[u]+cost; p.push({dis[v],v}); } } } } void print(int a,int b){ int ans=0; //如果该路径上存在已经被毁坏的就更新ans while(b!=a){ ans+=edges[b][path[b]]; b=path[b]; } cout<<ans<<endl; } signed main(){ cin>>n; cin>>m; for(int i=1;i<=m;i++){ int u,v,w; cin>>u>>v>>w; mapp[u].push_back({v,w}); mapp[v].push_back({u,w}); } cin>>d; for(int i=1;i<=d;i++){ int u,v,w; cin>>u>>v; for(int i=0;i<mapp[u].size();i++){ if(mapp[u][i].first==v){ w=mapp[u][i].second;//遍历找到对应权值(如果用邻接矩阵就不用了 } } edges[u][v]=w;//只存储被损坏的边 edges[v][u]=w; } cin>>A>>B; dijkstra(); print(A,B); return 0; }