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;
    }
  • 相关阅读:
    你人生中的那口井挖了没有?
    SQL Server 中WITH (NOLOCK)浅析
    如何用SQL语句查询Excel数据?
    ASP.NET Core中的依赖注入(2):依赖注入(DI)
    ASP.NET Core中的依赖注入(1):控制反转(IoC)
    wx小程序的学习
    Mac OS 下安装mysql环境
    Mac 全局变量 ~/.bash_profile 文件不存在的问题
    延期风险原因总结
    homebrew osx下面最优秀的包管理工具
  • 原文地址:https://www.cnblogs.com/zbtrs/p/8451962.html
Copyright © 2011-2022 走看看