1416 Warfare And Logistics ( 最短路樹)
阿新 • • 發佈:2018-12-10
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; } /* */