标签:uva
Description
The army of United Nations launched a new wave of air strikes on terrorist forces. The objective of the mission is to reduce enemy’s logistical mobility. Each air strike will destroy a path and therefore increase the shipping cost of the shortest path between two enemy locations. The maximal damage is always desirable.
Let’s assume that there are n enemy locations connected by m bidirectional paths, each with specific shipping cost. Enemy’s total shipping cost is given as c =
Input
The first line ofeach input case consists ofthree integers: n , m , and L . 1 < n
Output
For each case, output the total shipping cost before the air strike and the maximal total shipping cost after the strike. Output them in one line separated by a space.
Sample Input
4 6 1000
1 3 2
1 4 4
2 1 3
2 3 3
3 4 1
4 2 2
Sample Output
28 38
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <cmath>
#include <cstdlib>
#include <queue>
using namespace std;
const int N = 200;
const int M = 5005;
const int INF = 0x3f3f3f3f;;
typedef long long ll;
int n, m, l;
ll Dis[N];
struct Edge{
int from,to;
ll dist;
int flag;
};
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[M]; //每个结点出发的边编号(从0开始编号)
vector<int> tree[M];
bool done[N]; //是否已永久标号
int d[N]; //s到各个点的距离
int p[N]; //最短路中的上一条边
ll L;
void init(int n, ll l) {
this->n = n;
for(int i = 0; i <= m * 2; i++) {
G[i].clear();//清空邻接表
tree[i].clear();
}
memset(p, -1, sizeof(p));
edges.clear();//清空边表
this->L = l;
}
void addEdge(int from, int to, ll dist, int flag) {
//如果是无向图,每条无向边需调用两次AddEdge
edges.push_back((Edge){from, to, dist, flag});
m = edges.size();
G[from].push_back(m - 1);
}
ll dijkstra(int s) {//求s到所有点的距离
priority_queue<HeapNode> Q;
for(int i = 0; i <= n; i++) d[i] = INF;
d[s] = 0;
memset(done, 0, sizeof(done));
Q.push((HeapNode){0, s});
while(!Q.empty()){
HeapNode x = Q.top(); Q.pop();
int u = x.u;
if(done[u]) continue;
done[u] = true;
for(int i = 0; i < G[u].size(); i++){
Edge& e = edges[G[u][i]];
if(!e.flag) continue;
if(d[e.to] > d[u] + e.dist){
d[e.to] = d[u] + e.dist;
p[e.to] = G[u][i];
Q.push((HeapNode){d[e.to], e.to});
}
}
}
ll ans = 0;
for (int i = 1; i <= n; i++) {
if (i == s) continue;
if (d[i] == INF) ans += L;
else ans += d[i];
}
return ans;
}
void getTree(int s) {
for (int i = 1; i <= n; i++) {
if (i == s || p[i] == -1) continue;
tree[p[i]].push_back(s);
}
}
void deleteEdge(int x) {
edges[x].flag = 0;
edges[x^1].flag = 0;
}
void recoverEdge(int x) {
edges[x].flag = 1;
edges[x^1].flag = 1;
}
}dij;
void input() {
int u, v;
ll dis;
for (int i = 0; i < m; i++) {
scanf("%d %d %lld", &u, &v, &dis);
if (u == v) continue;
dij.addEdge(u, v, dis, 1);
dij.addEdge(v, u, dis, 1);
}
}
void solve() {
ll ans1 = 0, ans2, temp;
for (int i = 1; i <= n; i++) {
Dis[i] = dij.dijkstra(i);
ans1 += Dis[i];
dij.getTree(i);
}
ans2 = ans1;
for (int i = 0; i < dij.edges.size(); i++) {
dij.deleteEdge(i);
if (i % 2 == 0) temp = ans1;
for (int j = 0; j < dij.tree[i].size(); j++) {
temp -= Dis[dij.tree[i][j]];
temp += dij.dijkstra(dij.tree[i][j]);
}
dij.recoverEdge(i);
ans2 = max(ans2, temp);
}
printf("%lld %lld\n", ans1, ans2);
}
int main() {
while (scanf("%d %d %d", &n, &m, &l) == 3) {
dij.init(n, l);
input();
solve();
}
return 0;
}
版权声明:本文为博主原创文章,未经博主允许不可转载。
uva 1416 Warfare And Logistics (最短路树)
标签:uva
原文地址:http://blog.csdn.net/llx523113241/article/details/47427149