牛客暑假多校 F RIKKA with Line Graph

题意:

现在有一副完全图, 将他转化成线图。

线图就是 把原来的图上的边都变成点, 然后如果原来的任意2条边存在公共点, 他们就会有一条边, 边权为原来的2条边的和。

最后求出线图中的任意2点的最短路的和。

题解:

对于原图来说 

现在有 ( a, b)  ->  (c, d)  他的花费是 W(a,b) + W(c, d) + 2*min( d[a][c], d[a][d], d[b][c], d[b][d] ) 的值。其中d[i][j] 代表 从i走到j的最小花费。
现在我们枚举起点(i, j) 然后对于其他点都找到 min(d[a][i], d[a][j])
然后把这个值sort一遍, 每个位置的贡献就是他后面的数目的个数。
 
代码:
 1 #include<bits/stdc++.h>
 2 using namespace std;
 3 #define Fopen freopen("_in.txt","r",stdin); freopen("_out.txt","w",stdout);
 4 #define LL long long
 5 #define ULL unsigned LL
 6 #define fi first
 7 #define se second
 8 #define pb push_back
 9 #define lson l,m,rt<<1
10 #define rson m+1,r,rt<<1|1
11 #define lch tr[x].son[0]
12 #define rch tr[x].son[1]
13 #define max3(a,b,c) max(a,max(b,c))
14 #define min3(a,b,c) min(a,min(b,c))
15 typedef pair<int,int> pll;
16 const int inf = 0x3f3f3f3f;
17 const LL INF = 0x3f3f3f3f3f3f3f3f;
18 const LL mod = 998244353;
19 const int N = 505;
20 int d[N][N];
21 int dd[N*N];
22 int main(){
23     int T, n;
24     scanf("%d", &T);
25     while(T--){
26         scanf("%d", &n);
27         LL ans = 0;
28         for(int i = 1; i <= n; i++)
29             for(int j = 1; j <= n; j++){
30                 scanf("%d", &d[i][j]);
31                 if(i < j)
32                 ans = (ans+d[i][j])%mod;
33             }
34         int t = n*(n-1)/2 - 1;
35         ans = ans * t % mod;
36         for(int k = 1; k <= n; k++)
37             for(int i = 1; i <= n; i++)
38                 for(int j = 1; j <= n; j++)
39                     d[i][j] = min(d[i][j], d[i][k]+ d[k][j]);
40         for(int i = 1; i <= n; i++){
41             for(int j = i+1; j <= n; j++){
42                 int tt = 0;
43                 for(int k = 1; k <= n; k++){
44                     if(i == k || j == k) continue;
45                     else dd[++tt] = min(d[i][k], d[j][k]);
46                 }
47                 sort(dd+1, dd+1+tt);
48                 for(int k = 1; k < tt; k++)
49                     ans = (ans + 1ll * dd[k] * (tt-k)) % mod;
50             }
51         }
52         printf("%lld
", ans);
53     }
54     return 0;
55 }
View Code
原文地址:https://www.cnblogs.com/MingSD/p/9530875.html