题目链接:https://www.luogu.com.cn/problem/P3905
题目大意:
一些路坏了。求修复一些路使得A可以直接或间接到B的最小花费。
思路:
简单的迪杰斯特拉求A到B的最短路。
存图时注意:
1. 如果路没被破坏,权值设成0,因为不用修,不要钱。
2. 没了。
上代码
1 #include <cstdio> 2 #include <vector> 3 #define oo 2147483647 4 using namespace std; 5 struct edge { 6 int to,weight; 7 edge(int tt,int ww) { 8 this->to=tt; 9 this->weight=ww; 10 } 11 }; 12 int dis[110]; 13 bool vis[110]; 14 vector<edge> graph[110]; 15 void dij(int s,int n) { 16 fill(dis, dis + n + 1, oo); 17 dis[s] = 0; 18 int cnt = n; 19 while(cnt > 0) { 20 int Min = oo; 21 int x; 22 for(int i = 1; i <= n; ++i) { 23 if(!vis[i] && dis[i] < Min) { 24 Min = dis[i]; 25 x = i; 26 } 27 } 28 --cnt; 29 vis[x] = true; 30 int len = graph[x].size(); 31 for(int i = 0; i < len; ++i) { 32 int pos = graph[x][i].to; 33 if(dis[pos]>dis[x]+graph[x][i].weight){ 34 dis[pos]=dis[x]+graph[x][i].weight; 35 } 36 } 37 } 38 } 39 int getNumber(int i,int j){ 40 if (i<j) 41 { 42 return j*(j+1)/2+i; 43 } 44 45 return i*(i+1)/2+j; 46 } 47 int weightx[100*101/2]; 48 int main(int argc, char const *argv[]) { 49 int n,m; 50 scanf("%d",&n); 51 scanf("%d",&m); 52 for (int i = 1; i <= m; i++) { 53 int ii,j,k; 54 scanf("%d %d %d",&ii,&j,&k); 55 graph[ii].push_back(edge(j,0)); 56 graph[j].push_back(edge(ii,0)); 57 weightx[getNumber(ii,j)]=k; 58 } 59 int d; 60 scanf("%d",&d); 61 for(int i=1;i<=d;i++){ 62 int ii,j,jj,iii; 63 scanf("%d %d",&ii,&j); 64 for (jj = 0; graph[ii][jj].to!=j; jj++); 65 for (iii = 0; graph[j][iii].to!=ii; iii++); 66 graph[ii][jj].weight=weightx[getNumber(ii,j)]; 67 graph[j][iii].weight=weightx[getNumber(ii,j)]; 68 } 69 int a,b; 70 scanf("%d %d",&a,&b); 71 dij(a,n); 72 printf("%d",dis[b]); 73 return 0; 74 }
以后,我的文笔会越来越烂,敬请期待。
原文:https://www.cnblogs.com/eason66-blog/p/13543773.html