UVA1416 Warfare And Logistics

链接:http://acm.hust.edu.cn/vjudge/problem/viewProblem.action?id=36232

【题意】

给出一个无向图,定义C =∑(d[i][j])  ,其中d[][]表示两点间的最短距离,求出C并求出删除一条边后的最大C2。

【思路】

最短路树。

简单地想我们可以用floyd或SPFA求出两点间的最短距离,然后枚举删除m条边再次进行这项工作。

其实这里我们不用重新全部计算,因为如果所删除的边不在scr的最短路树上,那么这棵树不会被破坏。因此我们可以提前在求C的时候记录每一个scr最短路树上的边以及这棵最短路树的总权值,依旧枚举删边,判断是否需要重新计算即可。

理论上时间需要O(n^3),实践中应该能跑O(n^2)。

需要注意的是有重边的时候应该用次短边代替。

【代码】

 #include<cstdio>
#include<cstring>
#include<queue>
#include<vector>
#include<algorithm>
#define FOR(a,b,c) for(int a=(b);a<=(c);a++)
using namespace std; const int maxn = +,maxm=+;
const int INF=1e9;
struct Edge{
int u,v,w,next;
}; int n,m,L; struct SPFA{
int n;
Edge e[*maxm];
int en,front[maxn];
int inq[maxn],d[maxn];
int p[maxn];
queue<int> q; void init(int n){
this->n=n;
en=-;
memset(front,-,sizeof(front));
}
void AddEdge(int u,int v,int w) {
en++; e[en].u=u; e[en].v=v; e[en].w=w; e[en].next=front[u]; front[u]=en;
}
void solve(int s) {
memset(inq,,sizeof(inq));
memset(p,,sizeof(p));
for(int i=;i<=n;i++) d[i]=INF; d[s]=; inq[s]=; q.push(s);
while(!q.empty()) {
int u=q.front(); q.pop(); inq[u]=;
for(int i=front[u];i>=;i=e[i].next) {
int v=e[i].v,w=e[i].w;
if(w> && d[v]>d[u]+w) { //w<0表示此边已断
d[v]=d[u]+w;
p[v]=i;
if(!inq[v]) {
inq[v]=;
q.push(v);
}
}
}
}
}
}spfa; vector<int> gr[maxn][maxn]; //保存ij之间所有的边
int idx[maxn][maxn]; //边ij在SPFA中对应的编号
int used[maxn][maxn][maxn]; //used[scr][u][v]表示在scr为根的最短路树上边uv是否出现
int sum_single[maxn]; //scr的最短路树的d[]之和 int CALC_C() {
int ans=;
memset(used,,sizeof(used));
FOR(scr,,n)
{
spfa.solve(scr);
sum_single[scr]=;
FOR(v,,n)
{
if(v!=scr) {
int u=spfa.e[spfa.p[v]].u;
used[scr][u][v]=used[scr][v][u]=;
}
sum_single[scr] += spfa.d[v]==INF? L : spfa.d[v];
}
ans += sum_single[scr];
}
return ans;
}
int CALC_C2(int a,int b) {
int ans=;
FOR(scr,,n)
{
if(!used[scr][a][b]) ans+=sum_single[scr];
//如果边ij没有出现在i的最短路树上则无须重新计算
else
{
spfa.solve(scr);
FOR(v,,n) ans += spfa.d[v]==INF?L: spfa.d[v];
}
}
return ans;
} int main()
{
while(scanf("%d%d%d",&n,&m,&L)==) //==3 否则会TLE
{
int u,v,w;
spfa.init(n);
FOR(i,,n) FOR(j,,n) gr[i][j].clear();
while(m--) {
scanf("%d%d%d",&u,&v,&w);
gr[u][v].push_back(w);
gr[v][u].push_back(w);
}
FOR(i,,n) FOR(j,i+,n) if(!gr[i][j].empty()){
sort(gr[i][j].begin(),gr[i][j].end());
spfa.AddEdge(i,j,gr[i][j][]);
idx[i][j]=spfa.en;
spfa.AddEdge(j,i,gr[i][j][]);
idx[j][i]=spfa.en;
}
int c=CALC_C(),c2=-;
FOR(i,,n) FOR(j,i+,n) if(!gr[i][j].empty()){
int& e1=spfa.e[idx[i][j]].w;
int& e2=spfa.e[idx[j][i]].w;
if(gr[i][j].size()==) e1=e2=-;
else e1=e2=gr[i][j][]; //用次短边代替
c2=max(c2,CALC_C2(i,j)); //"删除" ij之间的边之后计算c2
e1=e2=gr[i][j][];
}
printf("%d %d\n",c,c2);
}
return ;
}

UVA1416 Warfare And Logistics的更多相关文章

  1. LA4080/UVa1416 Warfare And Logistics 最短路树

    题目大意: 求图中两两点对最短距离之和 允许你删除一条边,让你最大化删除这个边之后的图中两两点对最短距离之和. 暴力:每次枚举删除哪条边,以每个点为源点做一次最短路,复杂度\(O(NM^2logN)\ ...

  2. 【UVA1416】(LA4080) Warfare And Logistics (单源最短路)

    题目: Sample Input4 6 10001 3 21 4 42 1 32 3 33 4 14 2 2Sample Output28 38 题意: 给出n个节点m条无向边的图,每条边权都为正.令 ...

  3. UVA1416/LA4080 Warfare And Logistics

    题目大意:有N个点,M条路,如果两条路不连通的话,就将这两条路的距离设置为L 现在要求你求出每两点之间的最短距离和 接着要求 求出炸断 给出的M条路中的一条路后,每两点之间的最短距离和的最大值(翻译来 ...

  4. Warfare And Logistics UVA - 1416

    题目链接:https://vjudge.net/problem/UVA-1416 题解: 这是一个最短路的好题,首先我们考虑如果暴力弗洛伊德,显然时间复杂度不对,如果做n次spfa好像复杂度也不对,所 ...

  5. UVA 4080 Warfare And Logistics 战争与物流 (最短路树,变形)

    题意: 给一个无向图,n个点,m条边,可不连通,可重边,可多余边.两个问题,第一问:求任意点对之间最短距离之和.第二问:必须删除一条边,再求第一问,使得结果变得更大. 思路: 其实都是在求最短路的过程 ...

  6. uva 1416 Warfare And Logistics

    题意: 给出一个无向图,定义这个无向图的花费是 其中path(i,j),是i到j的最短路. 去掉其中一条边之后,花费为c’,问c’ – c的最大值,输出c和c’. 思路: 枚举每条边,每次把这条边去掉 ...

  7. UVA - 1416 Warfare And Logistics (最短路)

    Description The army of United Nations launched a new wave of air strikes on terroristforces. The ob ...

  8. UVALive 4080 Warfare And Logistics (最短路树)

    很多的边会被删掉,需要排除一些干扰进行优化. 和UVA - 1279 Asteroid Rangers类似,本题最关键的地方在于,对于一个单源的最短路径来说,如果最短路树上的边没有改变的话,那么最短路 ...

  9. la4080 Warfare And Logistics 罗列+最短

    为了图.计算最短随机分ans1.和删除边缘.免费才能够获得最大和短路之间的最大分ans2,如果这两个不沟通.看作是两个点之间的最短距离l. 第一个想法是枚举每个边缘,然后运行n最短时间.但是,这种复杂 ...

随机推荐

  1. .NET中的消息队列

    下文参考:http://hi.baidu.com/21tian/blog/item/ce5464097ddf10cb3ac76335.html为何使用消息队列 您可能认为您能够通过一个简单的数据库表( ...

  2. sql server获取当前日期

    SqlServer中得到当前日期(convert函数,getdate函数)函数GETDATE()的返回值在显示时只显示到秒.实际上,SQL Sever内部时间可以精确到毫秒级(确切地说,可以精确到3. ...

  3. cocos2dx入门分析 hello world

    打开新建的"findmistress"项目,可以看到项目文件是由多个代码文件及文件夹组成的,其中 Hello World 的代码文件直接存放于该项目文件夹中.下面我们来详细介绍一下 ...

  4. 生产者与消费者(三)---BlockingQueue

    前面阐述了实现生产者与消费者问题的两种方式:wait() / notify()方法 和 await() / signal()方法,本文继续阐述多线程的经典问题---生产者与消费者的第三种方式:Bloc ...

  5. SVM对偶形式

    dual svm 对偶SVM linear SVM 可以用二次规划方法解 xn通过非线性转换变成zn SVM配合非线性特征转换 透过large-margin降低模型复杂度 透过特征转换得到弯弯曲曲的边 ...

  6. C语言运算符与表达式

    1 概论 计算机内存中的数据可以通过变量,常量来表示和存储,那么这些数据如何运算? C语言中提供了大量(34种)的运算符可以用来完成数据的算术,赋值,逻辑,关系,条件判断以及自增自减运算和基于二进制的 ...

  7. 祭奠一年前写 Direct2D demo

    一年前, 用Direct2D实现了不怎么样的UI库. 用不怎么样的UI库实现了这个Demo. 当时放进某群共享, 以此装逼. 今天无意中翻出来, 解压, 什么都没变, 还是压缩前的模样. 不经意看见被 ...

  8. maven项目显示红叉的解决方法

    我们在做maven项目时,有时项目会显示红叉,但是项目本身并没有错误,如何去掉呢? 下面是我的解决方法 1.点击项目再右键,在搜索框中输入facets 2.把Dynamic Web Module的版本 ...

  9. Windows phone 之手势识别(Drag)

    首先,在XAML页面中,添加如下代码: 前提,别忘了添加 1.引入dll (silverlight for wndows phone toolkit) 2.引入命名空间 xmlns:toolkit=& ...

  10. 1.document.write(""); 输出语句

    1.document.write(""); 输出语句 2.JS中的注释为// 3.传统的HTML文档顺序是:document->html->(head,body) 4. ...