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

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

思路:

  其实都是在求最短路的过程。

  第一问可以floyd解决,也可以SSSP解决。注意是任意两个点,(a,b)和(b,a)是不同的,都要算。

  第二问要穷举删除每条边,再求第一问。为了降低复杂度,假设用dijkstra求最短路,那么可以利用第一问中所生成的树,共n棵,每棵至多n-1条边,如果穷举的边不在该某树上,那么该树的所有路径长不变,不必计算,否则需要计算。所以需要记录路径,并将整棵树的边集存起来,同时保存每棵树的任意两点路径之和。

  用结构体可以解决重边,问题应该不多,要注意各种细节,错了就重新打,也许更快。

  

  1 #include <bits/stdc++.h>
  2 #define LL long long
  3 #define pii pair<int,int>
  4 #define INF 0x7f7f7f7f
  5 using namespace std;
  6 const int N=220;
  7 int n, m, l, edge_cnt;
  8 vector<int> vect[N];
  9
 10 struct node
 11 {
 12     int from, to, dis,tag;
 13     node(){};
 14     node(int from,int to,int dis,int tag):from(from),to(to),dis(dis),tag(tag){};
 15 }edge[2050];
 16
 17 void add_node(int from,int to,int dis,int tag)
 18 {
 19     edge[edge_cnt]=node(from, to, dis, tag);
 20     vect[from].push_back(edge_cnt++);
 21 }
 22
 23 int dist[N], vis[N], path[N];
 24 LL dijkstra(int s)
 25 {
 26     memset(dist,0x7f,sizeof(dist));
 27     memset(vis,0,sizeof(vis));
 28     for(int i=0; i<=n; i++) path[i]=-1;
 29
 30     priority_queue<pii,vector<pii>,greater<pii> >   que;
 31     dist[s]=0;
 32     que.push(make_pair(0,s));
 33
 34     while(!que.empty())
 35     {
 36         int x=que.top().second;que.pop();
 37         if(vis[x])  continue;
 38         vis[x]=1;
 39         for(int i=0; i<vect[x].size(); i++)
 40         {
 41             node e=edge[vect[x][i]];
 42             if(e.tag>0 && dist[e.to]>dist[e.from]+e.dis )
 43             {
 44                 path[e.to]=vect[x][i];
 45                 dist[e.to]=dist[e.from]+e.dis;
 46                 que.push(make_pair(dist[e.to], e.to));
 47             }
 48         }
 49     }
 50
 51     LL sum=0;
 52     for(int i=1; i<=n; i++ )
 53     {
 54         if(dist[i]>=INF)    sum+=l;//不可达的,按L算
 55         else    sum+=dist[i];
 56     }
 57     return sum;
 58 }
 59
 60 LL ans1[N];
 61 int cal()
 62 {
 63     memset(ans1,0,sizeof(ans1));
 64     LL  first=0;
 65     unordered_set<int> tree[N];
 66     for(int i=1; i<=n; i++)
 67     {
 68         ans1[i]=dijkstra(i);
 69         first+=ans1[i];
 70         //收集边
 71         for(int k=1; k<=n; k++)
 72         {
 73             if(path[k]>=0)//注意如何初始化
 74             {
 75                 tree[i].insert(path[k]);
 76                 tree[i].insert(path[k]^1);
 77             }
 78         }
 79     }
 80     //另一个问
 81     LL second=0;
 82     for(int i=0; i<edge_cnt; i+=2)
 83     {
 84         edge[i].tag=edge[i+1].tag=0;
 85         LL sum=0;
 86         for(int j=1; j<=n; j++)
 87         {
 88             if( tree[j].find(i)==tree[j].end() )  //是点j的树上,要重新算
 89                 sum+=ans1[j];
 90             else
 91                 sum+=dijkstra(j);
 92         }
 93         second=max(second, sum);
 94         edge[i].tag=edge[i+1].tag=1;
 95     }
 96     printf("%lld %lld\n", first, second );//仅1个空格
 97 }
 98
 99 int main()
100 {
101     freopen("input.txt", "r", stdin);
102     int a, b, c;
103     while(scanf("%d%d%d", &n, &m, &l)==3)
104     {
105         edge_cnt=0;
106         memset(edge,0,sizeof(edge));
107         for(int i=0; i<=n; i++) vect[i].clear();
108         for(int i=0; i<m; i++)
109         {
110             scanf("%d%d%d",&a,&b,&c);
111             if(a==b)    continue;
112             add_node(a,b,c,1);
113             add_node(b,a,c,1);
114         }
115         cal();
116     }
117     return 0;
118 }

AC代码

时间: 2024-08-01 14:47:37

UVA 4080 Warfare And Logistics 战争与物流 (最短路树,变形)的相关文章

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 (最短路)

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

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

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

训练指南 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

本题最关键的地方在于,对于一个单源的最短路径来说,如果最短路树上的边没有改变的话,那么最短路肯定是不会变的, 所以只要枚举删掉最短路树上的边.这样的时间复杂度就能过了. 瞎搞真删边,结果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

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).虽然看上去比之前的好,但由于佛洛依德算法的常数很小,实际运行时间差不多.这时候,可以考虑最短路树.因为在源点确定的情况下,只要最短路树不被破坏,起点到所有点的距离都不会发生改变.也就

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

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