UVALive 4080 Warfare And Logistics(最短路树)
来源:互联网 发布:5.1声道测试软件 编辑:程序博客网 时间:2024/05/18 13:46
题目:https://icpcarchive.ecs.baylor.edu/index.php?option=com_onlinejudge&Itemid=8&page=show_problem&problem=2081
题目大意:给你n个点m条双向边的图。d(i,j)表示以 i 为源点时,j 到i的最短路。让你算 c = d(1,1)+d(1,2)+..+.d(1,n)+d(2,1)+d(2,2)+...+d(2,n)+......+d(n,n),如果d(i,j)不连通, + 的时候就用输入的 l 代替,。然后你可以删掉一条边,使得上面那个 c 最大,并求出这个最大值。
解题思路:第一个问题很好解决,floyd 和 n 次 dij 或者 spfa 都可以。关键是删掉一条边那里。如果枚举删掉的边,那复杂度就是 m*n^3 ,换 dij 和 spfa 应该也差不多,都过不了。此时就要想到,不是无论删除哪条边,所有东西都要重新算的,只有那些在最短路树上的边被删除时,才需要重新算。所以就是先 dij 处理出 n 个最短路树和每个为源点时的最短路和。然后就是上面的步骤了,先判断要不要重新算就好了。这里有个陷阱的,就是有重边。如果你要删除了两个点之间的一条边,那么肯定是删的最短的那一条,因为要使 c 最大么,删掉后不是就没有边了,应该是第二短的边顶上,所以这里还要稍微处理一下。
其实我不会算上面这个算法的复杂度,求哪位好心的大神指点~~~
代码如下:
#include<cstdio>#include<cstring>#include<queue>#include<vector>#include<algorithm>using namespace std;typedef long long lld;const int INF = 0x0fffffff;const int MAXN = 111;vector<int> G[MAXN][MAXN];bool flag[MAXN][MAXN][2];void init(int n){ for(int i = 1;i <= n;i++) for(int j = 1;j <= n;j++) G[i][j].clear();}void add_edge(int s,int t,int val){ G[s][t].push_back(val); if(G[s][t].size() <= 2) flag[s][t][G[s][t].size()-1] = 1;}struct Node{ int id; int val; Node(int iid,int vval) { id = iid; val = vval; } bool operator < (const Node& tmp) const { return val > tmp.val; }};priority_queue<Node> q;bool done[MAXN];int d[MAXN];int p[MAXN][MAXN];int first;void dij(int s,int n){ for(int i = 1;i <= n;i++) d[i] = INF; d[s] = 0; p[s][s] = -1; q.push(Node(s,0)); memset(done,0,sizeof(done)); while(!q.empty()) { Node cur = q.top(); q.pop(); if(done[cur.id]) continue; done[cur.id] = 1; for(int i = 1;i <= n;i++) for(int j = 0;j < G[cur.id][i].size();j++) { if(flag[cur.id][i][j]) { int tmp = cur.val+G[cur.id][i][j]; if(tmp < d[i]) { d[i] = tmp; if(first) p[s][i] = cur.id; q.push(Node(i,tmp)); } break; } } }}lld cc[MAXN];int main(){ int n,m,l; while(~scanf("%d%d%d",&n,&m,&l)) { init(n); while(m--) { int a,b,c; scanf("%d%d%d",&a,&b,&c); add_edge(a,b,c); add_edge(b,a,c); } for(int i = 1;i <= n;i++) for(int j = 1;j <= n;j++) sort(G[i][j].begin(),G[i][j].end()); lld c = 0; first = 1; for(int i = 1;i <= n;i++) { dij(i,n); cc[i] = 0; for(int j = 1;j <= n;j++) { if(d[j] >= INF) cc[i] += l; else cc[i] += d[j]; } c += cc[i]; } first = 0; printf("%lld ",c); lld ans = 0; for(int i = 1;i <= n;i++) { for(int j = i+1;j <= n;j++) if(G[i][j].size()) { flag[i][j][0] = flag[j][i][0] = 0; lld tmp = 0; for(int s = 1;s <= n;s++) if(p[s][i] == j || p[s][j] == i) { dij(s,n); for(int k = 1;k <= n;k++) if(d[k] >= INF) tmp += l; else tmp += d[k]; } else tmp += cc[s]; flag[i][j][0] = flag[j][i][0] = 1; ans = max(ans,tmp); } } printf("%lld\n",ans); } return 0;}
0 0
- UVALive 4080 Warfare And Logistics(最短路树)
- UVALive 4080 Warfare And Logistics(Dijkstra+最短路树)
- uvalive 4080 Warfare And Logistics最短路树
- UVALive - 4080 Warfare And Logistics (SPFA+最短路树)
- uvalive 4080 Warfare And Logistics(最短路树)
- UVA 1416 - Warfare And Logistics(最短路树)
- UVA-1416-Warfare And Logistics(最短路树)
- LA4080 Warfare And Logistics (dijkstra+最短路树)
- uva1416 - Warfare And Logistics 最短路树优化
- UVALive4080[Warfare And Logistics] 最短路树+dijkstra
- 10-22 warfare and logistics(最短路树)
- UVA1416 Warfare And Logistics(LA4080)(最短路,5级)
- uva 1416 - Warfare And Logistics(最短路)
- uva1410题解Warfare And Logistics(LA4080)(最短路)
- la4080 Warfare And Logistics 枚举+最短路
- UVA - 1416 Warfare And Logistics (最短路)
- LA 4080 Warfare And Logistics 战争和物流 dijkstra 最短路树
- uva 1416 Warfare And Logistics (最短路径树)
- 微信模版设计说明书(Written By GuWen)
- 关于内核挂载文件系统的一些网页,,有空在学习吧
- 输入一个整数,输出所有相加等于这个数的算式
- 解析UML类图符号
- 01字串
- UVALive 4080 Warfare And Logistics(最短路树)
- struts2文件上传类型的过滤
- Unit8_problem1_复数类中的运算符重载
- 客户端程序设计
- 关于五子棋AI的一点小尝试
- CareerCup Find the usernames existing in both documents
- Android AIDL 必看内容
- 每一位Android开发者应该知道的Android体系架构和开发库
- @NotEmpty、@NotBlank、@NotNull