UVA1416 Warfare And Logistics
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的更多相关文章
- LA4080/UVa1416 Warfare And Logistics 最短路树
题目大意: 求图中两两点对最短距离之和 允许你删除一条边,让你最大化删除这个边之后的图中两两点对最短距离之和. 暴力:每次枚举删除哪条边,以每个点为源点做一次最短路,复杂度\(O(NM^2logN)\ ...
- 【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条无向边的图,每条边权都为正.令 ...
- UVA1416/LA4080 Warfare And Logistics
题目大意:有N个点,M条路,如果两条路不连通的话,就将这两条路的距离设置为L 现在要求你求出每两点之间的最短距离和 接着要求 求出炸断 给出的M条路中的一条路后,每两点之间的最短距离和的最大值(翻译来 ...
- Warfare And Logistics UVA - 1416
题目链接:https://vjudge.net/problem/UVA-1416 题解: 这是一个最短路的好题,首先我们考虑如果暴力弗洛伊德,显然时间复杂度不对,如果做n次spfa好像复杂度也不对,所 ...
- UVA 4080 Warfare And Logistics 战争与物流 (最短路树,变形)
题意: 给一个无向图,n个点,m条边,可不连通,可重边,可多余边.两个问题,第一问:求任意点对之间最短距离之和.第二问:必须删除一条边,再求第一问,使得结果变得更大. 思路: 其实都是在求最短路的过程 ...
- uva 1416 Warfare And Logistics
题意: 给出一个无向图,定义这个无向图的花费是 其中path(i,j),是i到j的最短路. 去掉其中一条边之后,花费为c’,问c’ – c的最大值,输出c和c’. 思路: 枚举每条边,每次把这条边去掉 ...
- UVA - 1416 Warfare And Logistics (最短路)
Description The army of United Nations launched a new wave of air strikes on terroristforces. The ob ...
- UVALive 4080 Warfare And Logistics (最短路树)
很多的边会被删掉,需要排除一些干扰进行优化. 和UVA - 1279 Asteroid Rangers类似,本题最关键的地方在于,对于一个单源的最短路径来说,如果最短路树上的边没有改变的话,那么最短路 ...
- la4080 Warfare And Logistics 罗列+最短
为了图.计算最短随机分ans1.和删除边缘.免费才能够获得最大和短路之间的最大分ans2,如果这两个不沟通.看作是两个点之间的最短距离l. 第一个想法是枚举每个边缘,然后运行n最短时间.但是,这种复杂 ...
随机推荐
- .NET中的消息队列
下文参考:http://hi.baidu.com/21tian/blog/item/ce5464097ddf10cb3ac76335.html为何使用消息队列 您可能认为您能够通过一个简单的数据库表( ...
- sql server获取当前日期
SqlServer中得到当前日期(convert函数,getdate函数)函数GETDATE()的返回值在显示时只显示到秒.实际上,SQL Sever内部时间可以精确到毫秒级(确切地说,可以精确到3. ...
- cocos2dx入门分析 hello world
打开新建的"findmistress"项目,可以看到项目文件是由多个代码文件及文件夹组成的,其中 Hello World 的代码文件直接存放于该项目文件夹中.下面我们来详细介绍一下 ...
- 生产者与消费者(三)---BlockingQueue
前面阐述了实现生产者与消费者问题的两种方式:wait() / notify()方法 和 await() / signal()方法,本文继续阐述多线程的经典问题---生产者与消费者的第三种方式:Bloc ...
- SVM对偶形式
dual svm 对偶SVM linear SVM 可以用二次规划方法解 xn通过非线性转换变成zn SVM配合非线性特征转换 透过large-margin降低模型复杂度 透过特征转换得到弯弯曲曲的边 ...
- C语言运算符与表达式
1 概论 计算机内存中的数据可以通过变量,常量来表示和存储,那么这些数据如何运算? C语言中提供了大量(34种)的运算符可以用来完成数据的算术,赋值,逻辑,关系,条件判断以及自增自减运算和基于二进制的 ...
- 祭奠一年前写 Direct2D demo
一年前, 用Direct2D实现了不怎么样的UI库. 用不怎么样的UI库实现了这个Demo. 当时放进某群共享, 以此装逼. 今天无意中翻出来, 解压, 什么都没变, 还是压缩前的模样. 不经意看见被 ...
- maven项目显示红叉的解决方法
我们在做maven项目时,有时项目会显示红叉,但是项目本身并没有错误,如何去掉呢? 下面是我的解决方法 1.点击项目再右键,在搜索框中输入facets 2.把Dynamic Web Module的版本 ...
- Windows phone 之手势识别(Drag)
首先,在XAML页面中,添加如下代码: 前提,别忘了添加 1.引入dll (silverlight for wndows phone toolkit) 2.引入命名空间 xmlns:toolkit=& ...
- 1.document.write(""); 输出语句
1.document.write(""); 输出语句 2.JS中的注释为// 3.传统的HTML文档顺序是:document->html->(head,body) 4. ...