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];

void addEdge(int u,int v,int w)
{
    to[ecnt] = v;
    nxt[ecnt] = head[u];
    wei[ecnt] = w;
    head[u] = ecnt++;
}

typedef pair<int,int> Node;
#define fi first
#define se second

int d[maxn],pa[maxn];
typedef long long ll;

void dijkstra(int n,int s,int L,bool flag,int e1,int e2)// e1 e2 边应该忽略
{
    priority_queue<Node,vector<Node>,greater<Node> > q;
    fill(d,d+n,L);
    d[s] = 0; q.push(Node(0,s)); pa[s] = -1;
    while(q.size()){
        Node x = q.top(); q.pop();
        int u = x.se;
        if(x.fi != d[u]) continue;
        for(int i = head[u]; ~i; i = nxt[i])if(i!=e1 && i!=e2) {
            int v = to[i];
            if(d[v] > d[u]+wei[i]){
                d[v] = d[u]+wei[i];
                if(flag) pa[v] = i; // 入边编号
                q.push(Node(d[v],v));
            }
        }
    }
}

ll cal(int n)
{
    ll ret = 0;
    for(int i = 0; i < n; i++){
        ret += d[i];
    }
    return ret;
}

void init()
{
    memset(head,-1,sizeof(head));
    ecnt = 0;
    memset(delta,0,sizeof(delta));
}

int main()
{
    //freopen("in.txt","r",stdin);
    int n,m,L;
    while(~scanf("%d%d%d",&n,&m,&L)){
        init();
         while(m--){
            int u,v,w; scanf("%d%d%d",&u,&v,&w);
            addEdge(--u,--v,w); addEdge(v,u,w);
        }
        ll ans1 = 0;
        vector<int> edges;
        for(int u = 0; u < n; u++){
            dijkstra(n,u,L,true,-1,-1);
            ll t  = cal(n);
            ans1 += t;
            for(int i = 0; i < n; i++){
                if(~pa[i]){
                    dijkstra(n,u,L,false,pa[i],pa[i]^1);
                    int eid = pa[i]&(~1);
                    if(!delta[eid]) edges.push_back(eid);
                    delta[eid] += cal(n)-t;
                }
            }
        }
        int MaxDelta = 0;
        for(int i = 0; i < (int)edges.size(); i++){
            MaxDelta = max(MaxDelta,delta[edges[i]]);
        }
        printf("%lld %lld\n",ans1,ans1+MaxDelta);
    }
    return 0;
}
时间: 2024-10-08 15:03:15

UVALive 4080 Warfare And Logistics的相关文章

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 4080 Warfare And Logistics 战争与物流 (最短路树,变形)

题意:给一个无向图,n个点,m条边,可不连通,可重边,可多余边.两个问题,第一问:求任意点对之间最短距离之和.第二问:必须删除一条边,再求第一问,使得结果变得更大. 思路: 其实都是在求最短路的过程. 第一问可以floyd解决,也可以SSSP解决.注意是任意两个点,(a,b)和(b,a)是不同的,都要算. 第二问要穷举删除每条边,再求第一问.为了降低复杂度,假设用dijkstra求最短路,那么可以利用第一问中所生成的树,共n棵,每棵至多n-1条边,如果穷举的边不在该某树上,那么该树的所有路径长不

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

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

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

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

la4080 Warfare And Logistics 罗列+最短

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