zoukankan      html  css  js  c++  java
  • Hdu2433 Travel

    Travel

    Time Limit: 10000/2000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)
    Total Submission(s): 3391    Accepted Submission(s): 1162

    Problem 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 always take the shortest way. There are M (M <= 3000) two-way roads connecting the towns, and the length of the road is 1.
          Let SUM be the total distance of the shortest paths between all pairs of the towns. Please write a program to calculate the new SUM after one of the M roads is destroyed.
    Input
          The input contains several test cases.
          The first line contains two positive integers N, M. The following M lines each contains two integers u, v, meaning there is a two-way road between town u and v. The roads are numbered from 1 to M according to the order of the input.
          The input will be terminated by EOF.
    Output
          Output M lines, the i-th line is the new SUM after the i-th road is destroyed. If the towns are not connected after the i-th road is destroyed, please output “INF” in the i-th line.
    Sample Input
    5 4 5 1 1 3 3 2 5 4 2 2 1 2 1 2
    Sample Output
    INF INF INF INF 2 2
    题目大意:我们定义一张图的最短路为任意两点的最短路之和。 给定一个无权无向图,求每条边被删除时的图的最短路。
    分析:做法挺巧妙的.
              任意两点最短路之和要怎么求?floyd?显然不必要,每条边边权都是1,从每个点开始做一次bfs复杂度是O(n^2),如果暴力枚举每一条边删掉然后做bfs,那么复杂度是O(n^2*m),有超时的危险.
       一个优化:对每个点建一棵从该点出发的最短路树,如果删除的边不在第i个点的最短路树上,删了没影响,直接统计这个最短路树的边权和就可以了,否则就重新计算一遍最短路树.
    #include <cstdio>
    #include <queue>
    #include <cstring>
    #include <iostream>
    #include <algorithm>
    
    using namespace std;
    
    const int maxn = 3010,inf = 0x7ffffff;
    
    int n,m,head[110],to[maxn * 2],nextt[maxn * 2],tot = 1,pre[110][110],num[110][110];
    int d[110],vis[110],sum[110];
    bool flag = true;
    
    struct node
    {
        int x,y;
    } e[maxn];
    
    void add(int x,int y)
    {
        to[tot] = y;
        nextt[tot] = head[x];
        head[x] = tot++;
    }
    
    void bfs(int s)
    {
        queue <int> q;
        q.push(s);
        for (int i = 1; i <= n; i++)
            d[i] = inf;
        memset(vis,0,sizeof(vis));
        vis[s] = 1;
        d[s] = 0;
        while (!q.empty())
        {
            int u = q.front();
            q.pop();
            for (int i = head[u]; i; i = nextt[i])
            {
                int v = to[i];
                if (!vis[v])
                {
                    pre[s][v] = u;
                    d[v] = d[u] + 1;
                    vis[v] = 1;
                    q.push(v);
                }
            }
        }
        for (int i = 1; i <= n; i++)
        {
            if(d[i] == inf)
            {
                flag = false;
                return;
            }
            else
                sum[s] += d[i];
        }
    }
    
    int bfs2(int s)
    {
        queue <int> q;
        q.push(s);
        for (int i = 1; i <= n; i++)
            d[i] = inf;
        memset(vis,0,sizeof(vis));
        vis[s] = 1;
        d[s] = 0;
        while (!q.empty())
        {
            int u = q.front();
            q.pop();
            for (int i = head[u]; i; i = nextt[i])
            {
                int v = to[i];
                if (!vis[v] && num[u][v])
                {
                    d[v] = d[u] + 1;
                    vis[v] = 1;
                    q.push(v);
                }
            }
        }
        int res = 0;
        for (int i = 1; i <= n; i++)
        {
            if (d[i] == inf)
                return -1;
            else
                res += d[i];
        }
        return res;
    }
    
    int main()
    {
        while (scanf("%d%d",&n,&m) != EOF)
        {
            memset(head,0,sizeof(head));
            tot = 1;
            flag = true;
            memset(pre,0,sizeof(pre));
            memset(sum,0,sizeof(sum));
            memset(num,0,sizeof(num));
            for (int i = 1; i <= m; i++)
            {
                int x,y;
                scanf("%d%d",&x,&y);
                num[x][y]++;
                num[y][x]++;
                e[i].x = x;
                e[i].y = y;
                add(x,y);
                add(y,x);
            }
            for (int i = 1; i <= n; i++)
            {
                bfs(i);
                if(!flag)
                    break;
            }
            if (!flag)
            {
                for (int i = 1; i <= m; i++)
                    puts("INF");
            }
            else
            {
                for (int i = 1; i <= m; i++)
                {
                    bool flag2 = true;
                    int ans = 0,x = e[i].x,y = e[i].y;
                    for (int j = 1; j <= n; j++)
                    {
                        if (pre[j][y] != x && pre[j][x] != y)
                        {
                            ans += sum[j];
                            continue;
                        }
                        else
                        {
                            num[x][y]--;
                            num[y][x]--;
                            int t = bfs2(j);
                            num[x][y]++;
                            num[y][x]++;
                            if (t == -1)
                            {
                                flag2 = false;
                                puts("INF");
                                break;
                            }
                            else
                                ans += t;
                        }
                    }
                    if (flag2)
                        printf("%d
    ",ans);
                }
            }
        }
    
        return 0;
    }
  • 相关阅读:
    最新28个很棒的 jQuery 教程
    NetBeans 为PHP添加调试功能
    HTML5 存储API介绍
    PHP 变量判断
    jquery 与其它js 框架的解决办法
    从按下电源开关到bash提示符
    tar、gzip、unzip命令的详细使用方法
    Top命令中Load Average的含义
    Linux(BASH)命令搜索机制
    分析df和du的区别
  • 原文地址:https://www.cnblogs.com/zbtrs/p/8451962.html
Copyright © 2011-2022 走看看