题意:无向图中有n个结点,m条边。需要求出所有结点之间最短路之和(若是两个结点间不能到达那么算成是x)例:n=2时 ans = d(1,1)+d(1,2)+d(2,1)+d(2,2)。然后从图中随机拿去一条边然后在让你计算所有结点之间最短路之和,问你可能得到的最大值是什么?
思路:这道题正解是要求出最短路树,但是给出一种更简单的做法就是spfa暴力。当时抱着试一试的思想写了一发,结果没想到就过了,然后速度在2s左右,还算可以。先算出所有点与点之间的最短路,然后在枚举删除边求最短路最大值就可。
代码如下:
1 #include <iostream> 2 #include <cstdio> 3 #include <cstring> 4 #include <cstdlib> 5 #include <cmath> 6 #include <algorithm> 7 #include <queue> 8 #include <stack> 9 #include <vector> 10 #define MP(a, b) make_pair(a, b) 11 #define PB(a) push_back(a) 12 13 using namespace std; 14 15 typedef long long ll; 16 typedef pair<int ,int> pii; 17 18 const ll INF = 0x3f3f3f3f3f3f3fLL; 19 const double eps = 1e-6; 20 const int LEN = 110; 21 22 vector<pii> Map[LEN]; 23 int n, m, l, u[1010], v[1010], w[1010]; 24 ll dis[LEN][LEN], lans, ans; 25 26 void SPFA(int s, int a, int b, int c){ 27 deque<int> q; 28 int vis[LEN] = {0}; 29 for(int i=1; i<=n; i++)dis[s][i] = INF; 30 dis[s][s] = 0; 31 q.push_back(s); 32 vis[s] = 1; 33 while(!q.empty()){ 34 int nv = q.front(); q.pop_front(); 35 for(int i=0; i<Map[nv].size(); i++){ 36 int x = Map[nv][i].first, y = Map[nv][i].second; 37 if((a==nv && b==x && c==y) || (a==x && b==nv &&c==y))continue; 38 if(dis[s][x]>dis[s][nv]+y){ 39 dis[s][x] = dis[s][nv]+y; 40 if(!vis[x]){ 41 vis[x] = 1; 42 if(!q.empty()){ 43 if(dis[s][x]>dis[s][q.front()])q.push_back(x); 44 else q.push_front(x); 45 }else q.push_back(x); 46 } 47 } 48 } 49 vis[nv]=0; 50 } 51 } 52 53 int main() 54 { 55 // freopen("in.txt", "r", stdin); 56 57 while(scanf("%d%d%d", &n, &m, &l)!=EOF){ 58 for(int i=0; i<=n; i++)Map[i].clear(); 59 for(int i=0; i<m; i++){ 60 scanf("%d%d%d", &u[i], &v[i], &w[i]); 61 Map[v[i]].PB(MP(u[i], w[i])); 62 Map[u[i]].PB(MP(v[i], w[i])); 63 } 64 lans = 0; 65 for(int i=1; i<=n; i++){ 66 SPFA(i,-1,-1,-1); 67 for(int j=1; j<=n; j++){ 68 if(dis[i][j]!=INF)lans += dis[i][j]; 69 else lans+=l; 70 } 71 } 72 ans = 0; 73 for(int i=0; i<m; i++){ 74 ll loc = 0; 75 for(int j=1; j<=n; j++){ 76 SPFA(j,u[i],v[i],w[i]); 77 for(int k=1; k<=n; k++){ 78 if(dis[j][k]!=INF)loc += dis[j][k]; 79 else loc+=l; 80 } 81 } 82 if(loc>ans)ans = loc; 83 } 84 printf("%lld %lld ", lans, ans); 85 } 86 return 0; 87 }