Warfare And Logistics UVALive - 4080 (最短路树)

Warfare And Logistics

UVALive - 4080

题意:给n个点m条边。令c为每对节点的最短路长度之和。要求删除一条边后使得新的c值c‘最大,不连通的两点对短路视为L。

【如果每次删除一条边,要跑m次dijkstra,其实其中很多次都对最短路没有影响,因为删掉的边不在最短路里】

【因此,可以每次删除最短路树中的一条边,需要跑n次,复杂度降低到可接受程度】

  1 #include <bits/stdc++.h>
  2 #define LL long long
  3 using namespace std;
  4 const int inf=0x3f3f3f3f;
  5 const int maxv=110;
  6 const int maxe=2010;
  7 int n,m,L;
  8 struct Edge
  9 {
 10     int u,v,w;
 11     int nex;
 12 }e[maxe<<1];
 13 int head[maxv];
 14 int cnt=0;
 15 void init()
 16 {
 17     memset(head,-1,sizeof(head));
 18     cnt=0;
 19 }
 20 void add(int u,int v,int w)
 21 {
 22     e[cnt].u=u;
 23     e[cnt].v=v;
 24     e[cnt].w=w;
 25     e[cnt].nex=head[u];
 26     head[u]=cnt++;
 27 }
 28
 29 typedef pair<int,int> PII;
 30 int dis[maxv],par[maxv];
 31 void dijkstra(int s,bool c,int e1)
 32 {
 33     priority_queue<PII,vector<PII>,greater<PII> > pq;
 34     for(int i=0;i<maxv;i++) dis[i]=L;
 35     dis[s]=0;
 36     pq.push(PII(0,s));
 37     par[s]=-1;
 38     while(!pq.empty())
 39     {
 40         PII t=pq.top();
 41         pq.pop();
 42         int u=t.second;
 43         if(dis[u]<t.first) continue;
 44         for(int i=head[u];i!=-1;i=e[i].nex)
 45         {
 46             if(i==e1||i==(e1^1)) continue;   //
 47             int v=e[i].v;
 48             if(dis[v]>dis[u]+e[i].w)
 49             {
 50                 dis[v]=dis[u]+e[i].w;
 51                 if(c) par[v]=i;
 52                 pq.push(PII(dis[v],v));
 53             }
 54         }
 55     }
 56 }
 57 LL cal()
 58 {
 59     LL temp=0;
 60     for(int i=0;i<n;i++)
 61         temp+=dis[i];
 62     return temp;
 63 }
 64 vector<int> vv;
 65 int delta[maxe];
 66
 67 int main()
 68 {
 69     while(scanf("%d%d%d",&n,&m,&L)!=EOF)
 70     {
 71         init();
 72         int u,v,w;
 73         for(int i=0;i<m;i++)
 74         {
 75             scanf("%d%d%d",&u,&v,&w);
 76             u--;v--;
 77             add(u,v,w);
 78             add(v,u,w);
 79         }
 80         LL ans=0;
 81         vv.clear();
 82         memset(delta,0,sizeof(delta));
 83         for(int i=0;i<n;i++)
 84         {
 85             dijkstra(i,1,-1);
 86             LL temp=cal();
 87             ans+=temp;
 88             for(int j=0;j<n;j++)
 89                 if(par[j]!=-1)
 90             {
 91                 dijkstra(i,0,par[j]);
 92                 int id=par[j]&(~1);   //
 93                 if(!delta[id]) vv.push_back(id);
 94                 delta[id]+=cal()-temp;
 95             }
 96
 97         }
 98         int maxdelta=0;
 99         for(int i=0;i<(int)vv.size();i++)
100             maxdelta=max(maxdelta,delta[vv[i]]);
101         printf("%lld %lld\n",ans,ans+maxdelta);
102     }
103 }

时间: 2024-08-07 14:39:30

Warfare And Logistics UVALive - 4080 (最短路树)的相关文章

训练指南 UVALive - 4080(最短路Dijkstra + 边修改 + 最短路树)

layout: post title: 训练指南 UVALive - 4080(最短路Dijkstra + 边修改 + 最短路树) author: "luowentaoaa" catalog: true mathjax: true tags: - Dijkstra - 最短路树 - 图论 - 训练指南 Warfare And Logistics UVALive - 4080 题意 ①先求任意两点间的最短路径累加和,其中不连通的边权为L ②删除任意一条边,求全局最短路径和的最大值 题解

UVALive - 4080 Warfare And Logistics (SPFA+最短路树)

题目大意:有N个点,M条路,如果两条路不连通的话,就将这两条路的距离设置为L 现在要求你求出每两点之间的最短距离和 接着要求 求出炸断 给出的M条路中的一条路后,每两点之间的最短距离和的最大值 解题思路:这题跟HDU-2433类似,不过这题的权值是不一样的 但具体的思路是差不多的 先预处理出以每个点为源点的最短路树,并纪录每个点的pre和以每个点为源点的最短距离和,这样就可以求出每两点之间的最短距离和了 接着依次删边,如果删除的边不在该点最短路树上,那么就可以用预处理纪录的以该点为源点的最短距离

UVALive 4080 Warfare And Logistics(Dijkstra+最短路树)

 题意:给定一个n节点m条边的无向图,定义c为每对顶点的最短路之和,要求删掉一条边重新求一个c值c',求出c'最大值. 思路:如果用floyd算法计算c,每尝试删除一条边都要重新计算一次,时间复杂度为O(n*n*n*m),很难承受.如果用n次Dijkstra计算单源最短路,时间复杂度味O(n*m*m*logn).虽然看上去比之前的好,但由于佛洛依德算法的常数很小,实际运行时间差不多.这时候,可以考虑最短路树.因为在源点确定的情况下,只要最短路树不被破坏,起点到所有点的距离都不会发生改变.也就

uva 1416 Warfare And Logistics (最短路树)

uva 1416 Warfare And Logistics 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 inc

UVA 1416 - Warfare And Logistics(最短路树)

UVA 1416 - Warfare And Logistics 题目链接 题意:给定一个无向图,每个边一个正权,c等于两两点最短路长度之和,现在要求删除一边之后,新图的c值最大的是多少 思路:直接枚举删边,每次做一次dijkstra的话复杂度太高,其实如果建好最短路树,如果删去的边在最短路树上,才需要去做,这样复杂度就优化到(n^2mlog(n)),勉强可以接受 代码: #include <cstdio> #include <cstring> #include <vecto

UVALive 4080 Warfare And Logistics

本题最关键的地方在于,对于一个单源的最短路径来说,如果最短路树上的边没有改变的话,那么最短路肯定是不会变的, 所以只要枚举删掉最短路树上的边.这样的时间复杂度就能过了. 瞎搞真删边,结果T了... #include<bits/stdc++.h> using namespace std; const int maxn = 102, maxm = 2002; int head[maxn], to[maxm], nxt[maxm],wei[maxm],ecnt; int delta[maxm]; v

la4080 Warfare And Logistics 罗列+最短

为了图.计算最短随机分ans1.和删除边缘.免费才能够获得最大和短路之间的最大分ans2,如果这两个不沟通.看作是两个点之间的最短距离l. 第一个想法是枚举每个边缘,然后运行n最短时间.但是,这种复杂性是1000*1000*100*log(100),太大了..事实上在固定起点,求出单元最短路的时候.同一时候能够求出单源最短路树,仅仅有删除的边在树上的时候.源点到任一点的最短路才会有变化,所以在每次跑单源最短路的时候,仅仅须要枚举树上的n-1条边就能够了.累加一下删除每一条边时,在当前源点的情况下

UVA 1416 最短路树

Warfare And Logistics The army of United Nations launched a new wave of air strikes on terroristforces. The objective of the mission is to reduce enemy's logistical mobility. Each airstrike will destroy a path and therefore increase the shipping cost

UVA - 1416 Warfare And Logistics (最短路)

Description The army of United Nations launched a new wave of air strikes on terroristforces. The objective of the mission is to reduce enemy's logistical mobility. Each airstrike will destroy a path and therefore increase the shipping cost of the sh