题目链接:https://cn.vjudge.net/problem/UVA-1416
c比较容易求,cc如果一条边一条边枚举的话,每删除一条边,就要再求一遍任意两点的最短路,无论是跑一遍floyd或n-1遍dij时间复杂度都很大,我们可以用最短路树来优化一下,只有删除最短路树上的边,我们再重新求最短路,删除不是最短路树上的边,任意两点的最短路是不变的,这样时间复杂度就降了下来,因为每一个源点的最短路树只有n-1条,求最短路树只需要记录一下路径就可以了
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const int MAXN = 205;
const int MAXM = 2005;
const int INF = 0x3f3f3f3f;
struct Edge
{
int to,Next,w;
}edge[MAXM];
int tot,head[MAXN];
int dis[MAXN][MAXN],pre[MAXN][MAXN];
int a[MAXN];
bool vis[MAXN];
void init()
{
tot = 0;
memset(head,-1,sizeof(head));
memset(pre,0,sizeof(pre));
memset(a,0,sizeof(a));
}
void addedge(int u,int v,int w)
{
edge[tot].to = v;
edge[tot].w = w;
edge[tot].Next = head[u];
head[u] = tot++;
}
struct node
{
int u;
int dis;
node(){}
node(int _u,int _dis)
{
u = _u;
dis = _dis;
}
bool operator < (const struct node& a) const
{
return dis > a.dis;
}
};
int n,l;
void Dijkstra(int s)
{
struct node t;
for(int i = 1; i <= n; i++) {
vis[i] = false;
dis[s][i] = INF;
}
dis[s][s] = 0;
priority_queue<node> pq;
pq.push(node(s,0));
while(!pq.empty()) {
t = pq.top();
pq.pop();
int u = t.u;
if(vis[u]) continue;
vis[u] = true;
for(int i = head[u]; i != -1; i = edge[i].Next) {
int v = edge[i].to;
if(dis[s][v] > dis[s][u] + edge[i].w) {
pre[s][v] = u;
dis[s][v] = dis[s][u] + edge[i].w;
pq.push(node(v,dis[s][v]));
}
}
}
for(int i = 1; i <= n; i++) {
if(dis[s][i] >= INF) {
dis[s][i] = l;
}
}
}
int main(void)
{
int m,u,v,w;
int ans1,ans2;
while(scanf("%d %d %d",&n,&m,&l) != EOF) {
ans1 = ans2 = 0;
init();
while(m--) {
scanf("%d %d %d",&u,&v,&w);
addedge(u,v,w);
addedge(v,u,w);
}
for(int i = 1; i <= n; i++) {
Dijkstra(i);
}
for(int i = 1; i <= n; i++) {
for(int j = 1; j <= n; j++) {
a[i] += dis[i][j];
ans1 += dis[i][j];
}
}
printf("%d ",ans1);
for(int i = 0; i < tot; i++) {
for(int j = head[i]; j != -1; j = edge[j].Next) {
int res = 0;
u = i,v = edge[j].to;
for(int k = 1; k <= n; k++) {
if(pre[k][v] != u && pre[k][u] != v) {
res += a[k];
continue;
}
int w = edge[j].w;
edge[j].w = INF;
edge[j ^ 1].w = INF;
Dijkstra(k);
for(int p = 1; p <= n; p++) {
res += dis[k][p];
}
edge[j].w = w;
edge[j ^ 1].w = w;
Dijkstra(k);
}
ans2 = max(ans2,res);
}
}
printf("%d\n",ans2);
}
return 0;
}
/*
*/