有、艹蛋
用来复习Dijkstra算法啦
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <vector>
#include <queue>
using namespace std;
const int INF = 0x7fffffff;
const int maxn = 100 + 10;
struct Edge{
int from, to, dist;
};
struct HeapNode{
int d, u;
bool operator < (const HeapNode& rhs) const {
return d > rhs.d;
}
};
struct Dijkstra{
int n, m;
vector<Edge> edges;
vector<int> G[maxn];
bool done[maxn];
int p[maxn], d[maxn];
void init(int n){
this -> n = n;
for (int i = 0; i < n; i++)
G[i].clear();
edges.clear();
}
void AddEdge(int from, int to, int dist){
edges.push_back((Edge){from, to, dist});
m = edges.size();
G[from].push_back(m - 1);
}
void dijkstra(int s){
priority_queue<HeapNode> que;
for (int i = 0; i < n; i++)
d[i] = INF;
d[s] = 0;
memset(done, 0, sizeof(done));
que.push((HeapNode){0, s});
while(!que.empty()){
HeapNode x = que.top(); que.pop();
int u = x.u;
if (done[u]) continue;
done[u] = 1;
for (int i = 0; i < G[u].size(); i++){
Edge& e = edges[G[u][i]];
if (e.dist >= 0 && d[e.to] > d[u] + e.dist){
d[e.to] = d[u] + e.dist;
p[e.to] = G[u][i];
que.push((HeapNode){d[e.to], e.to});
}
}
}
}
};
Dijkstra solver;
int n, m, L;
vector<int> gr[maxn][maxn];
int used[maxn][maxn][maxn];
int idx[maxn][maxn];
int sum_single[maxn];
int compute_c(){
int ans = 0;
memset(used, 0, sizeof(used));
for (int src = 0; src < n; src++){
solver.dijkstra(src);
sum_single[src] = 0;
for (int i = 0; i < n; i++){
if (i != src){
int fa = solver.edges[solver.p[i]].from;
used[src][fa][i] = used[src][i][fa] = 1;
}
sum_single[src] += (solver.d[i] == INF ? L : solver.d[i]);
}
ans += sum_single[src];
}
return ans;
}
int compute_newc(int a, int b){
int ans = 0;
for (int src = 0; src < n; src++)
if (!used[src][a][b]) ans += sum_single[src];
else{
solver.dijkstra(src);
for (int i = 0; i < n; i++)
ans += (solver.d[i] == INF ? L : solver.d[i]);
}
return ans;
}
int main(){
// freopen("in.txt", "r", stdin);
while(~scanf("%d%d%d", &n, &m, &L)){
solver.init(n);
for (int i = 0; i < n; i++)
for (int j = 0; j < n; j++)
gr[i][j].clear();
for (int i = 0; i < m; i++){
int x, y, z;
scanf("%d%d%d", &x, &y, &z);
x -= 1; y -= 1;
gr[x][y].push_back(z);
gr[y][x].push_back(z);
}
for (int i = 0; i < n; i++)
for (int j = i + 1; j < n; j++)
if (!gr[i][j].empty()){
sort(gr[i][j].begin(), gr[i][j].end());
solver.AddEdge(i, j, gr[i][j][0]);
idx[i][j] = solver.m - 1;
solver.AddEdge(j, i, gr[i][j][0]);
idx[j][i] = solver.m - 1;
}
int c = compute_c(), c2 = -1;
for (int i = 0; i < n; i++)
for (int j = i + 1; j < n; j++)
if (!gr[i][j].empty()){
int& e1 = solver.edges[idx[i][j]].dist;
int& e2 = solver.edges[idx[j][i]].dist;
if (gr[i][j].size() == 1) e1 = e2 = -1;
else e1 = e2 = gr[i][j][1];
c2 = max(c2, compute_newc(i, j));
e1 = e2 = gr[i][j][0];
}
printf("%d %d\n", c, c2);
}
return 0;
}