HDU - 2433 Travel (最短路树)

题目大意:有N个点,M条边,每次删掉一条边,问删掉该边后,所有点之间的最短路的和是多少

解题思路:刚开始就想,删掉一次floyd一次,结果可想而之,TLE了

后来看了别人的,发现了一种叫做最短路树的东西。

就是先求出以每个点为源点的最短路并纪录该点到每个点的距离和,和每个点的pre,这样的话,就预处理好了

因为要删掉边,前面我们已经预处理好了最短路树的pre,也就是说,就可以依次判断删除的边是否在最短路树上,只要你要删除的边不在该最短路树上,那么就没有影响了,可以直接用前面纪录的数据

如果要删掉的边有影响的话,那就将该边标记下,再跑一次最短路,求出最优解即可

#include <cstdio>
#include <cstring>
#include <queue>
#include <algorithm>
using namespace std;
#define N 110
#define M 6020
#define INF 0x3f3f3f3f

struct Edgs{
    int to, next;
}E[M];

struct Node {
    int x, y;
}node[M];

int d[N], pre[N][N], num[N][N], sum[N], head[N];
int cnt, n, m;
bool flag = true;
bool vis[N];

void add_edgs(int u, int v) {
    E[cnt].to = v;
    E[cnt].next = head[u];
    head[u] = cnt++;
}

void init(){
    memset(num, 0, sizeof(num));
    memset(head, -1, sizeof(head));
    cnt = 0;
    int x, y;
    for (int i = 0; i < m; i++) {
        scanf("%d%d", &x, &y);
        node[i].x = x;    node[i].y = y;
        num[x][y]++;      num[y][x]++;
        add_edgs(x, y);   add_edgs(y, x);
    }
}

void bfs(int s) {
    queue<int> q;
    for (int i = 1; i <= n; i++) {
        d[i] = INF;
        vis[i] = false;
    }
    d[s] = 0;
    pre[s][s] = 0;
    vis[s] = 1;
    q.push(s);

    while (!q.empty()) {
        int u = q.front();
        q.pop();

        for (int i = head[u]; i != -1; i = E[i].next) {
            int v = E[i].to;
            if (!vis[v]) {
                d[v] = d[u] + 1;
                vis[v] = 1;
                pre[s][v] = u;
                q.push(v);
            }
        }
    }
    sum[s] = 0;
    for (int i = 1; i <= n; i++) {
        if (d[i] == INF) {
            flag = false;
            return ;
        }
        sum[s] += d[i];
    }
}

int bfs2(int s) {
    queue<int> q;
    for (int i = 1; i <= n; i++) {
        vis[i] = false;
        d[i] = INF;
    }
    d[s] = 0;
    vis[s] = true;
    q.push(s);

    while (!q.empty()) {
        int u = q.front();
        q.pop();

        for (int i = head[u]; i != -1; i = E[i].next) {
            int v = E[i].to;
            if (num[u][v] && !vis[v]) {
                d[v] = d[u] + 1;
                vis[v] = true;
                q.push(v);
            }
        }
    }

    int ans = 0;
    for (int i = 1; i <= n; i++) {
        if (d[i] == INF)
            return -1;
        ans += d[i];
    }
    return ans;
}

void solve() {

    flag = true;
    for (int i = 1; i <= n; i++) {
        if (flag)
            bfs(i);
        else
            break;
    }

    for (int i = 0; i < m; i++) {

        if (!flag) {
            printf("INF\n");
            continue;
        }
        int x = node[i].x;
        int y = node[i].y;

        int ans = 0, j;
        for (j = 1; j <= n; j++) {
            if (pre[j][x] != y && pre[j][y] != x) {
                ans += sum[j];
                continue;
            }
            num[x][y]--; num[y][x]--;

            int t = bfs2(j);

            num[y][x]++; num[x][y]++;

            if (t == -1) {
                printf("INF\n");
                break;
            }
            ans += t;
        }
        if (j == n + 1)
            printf("%d\n", ans);
    }
}

int main() {
    while (scanf("%d%d", &n, &m) != EOF) {
        init();
        solve();
    }
    return 0;
}

版权声明:本文为博主原创文章,未经博主允许不得转载。

时间: 2024-10-25 00:59:39

HDU - 2433 Travel (最短路树)的相关文章

hdu 2433 Travel (最短路径树)

hdu 2433 Travel Description One day, Tom traveled to a country named BGM. BGM is a small country, but there are N (N <= 100) towns in it. Each town products one kind of food, the food will be transported to all the towns. In addition, the trucks will

HDU 2433 Travel

Travel Time Limit: 2000ms Memory Limit: 32768KB This problem will be judged on HDU. Original ID: 243364-bit integer IO format: %I64d      Java class name: Main One day, Tom traveled to a country named BGM. BGM is a small country, but there are N (N <

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

HDU 5441 Travel 并查集

HDU 5441 Travel 题意:一张无向图,q个查询,对于每个x,有多少对点之间的路径中最长的一条路不大于x. 思路:比赛时王秋平写的,我补下题.这题也比较简单,将边排序,从小到大加到并查集,对查询也排序,从小到大对于每个查询把不大于x的边加到并查集,用cnt[y]记录以y为根的连通块有多少节点,那么在连通块发生 变化时,ans=2 * cnt[x] * cnt[y] 1 #include <iostream> 2 #include <cstdio> 3 #include &

POJ1122_FDNY to the Rescue!(逆向建图+最短路树)

FDNY to the Rescue! Time Limit: 1000MS   Memory Limit: 10000K Total Submissions: 2368   Accepted: 721 Description The Fire Department of New York (FDNY) has always been proud of their response time to fires in New York City, but they want to make the

HDU 4571 Travel in time (SPFA 或 dp)

HDU 4571 大概题意:n个点(<=100)m条边(<=1000)的无向图,每个点有消耗costp和价值moneyp,每条边有消耗coste.问从点s出发到点e,消耗不超过t(<=300)所获得的最大价值.经过边必有消耗coste:经过点时,当取得价值moneyp时消耗costp,即为visit该点:当取得价值0,时消耗也为0,即为pass该点.visit的点的moneyp值必须是严格升序. 解法: 容易看出应该用spfa和dp来解.关键时对visit和pass点的处理. 通过flo

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

hdu 5380 Travel with candy(双端队列)

题目链接:hdu 5380 Travel with candy 保持油箱一直处于满的状态,维护一个队列,记录当前C的油量中分别可以以多少价格退货,以及可以推货的量.每到一个位置,可以该商店的sell值更新队列中所有价格小于sell的(还没有卖).用buy值更新队列中大于buy(卖掉了).移动所消耗的油从价格最低的开始. #include <cstdio> #include <cstring> #include <algorithm> using namespace st