hdu 2433 spfa

转载 2016年05月31日 14:36:28

Travel

TimeLimit: 10000/2000 MS (Java/Others)    Memory Limit:32768/32768 K (Java/Others)
Total Submission(s): 2580    Accepted Submission(s): 845

Problem Description

      Oneday, Tom traveled to a country named BGM. BGM is a small country, but there areN (N <= 100) towns in it. Each town products one kind of food, the food willbe transported to all the towns. In addition, the trucks will always take theshortest 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 theshortest paths between all pairs of the towns. Please write a program tocalculate the new SUM after one of the M roads is destroyed.

 

 

Input

      Theinput contains several test cases.
      The first line contains two positiveintegers N, M. The following M lines each contains two integers u, v, meaningthere is a two-way road between town u and v. The roads are numbered from 1 toM according to the order of the input.
      The input will be terminated by EOF.

 

 

Output

      OutputM lines, the i-th line is the new SUM after the i-th road is destroyed. If thetowns are not connected after the i-th road is destroyed, please output “INF”in the i-th line.

 

 

Sample Input

54

51

13

32

54

22

12

12

 

 

Sample Output

INF

INF

INF

INF

2

2

 

 

Source

2008 AsiaChengdu Regional Contest Online

 

 

题目是要求每次删除地i条边后以1,2,3,...n为起始点到其他点的最短路和的总和

分析:从题意可以想到用spfa,毕竟spfa是求单源多点的最短路的好算法, 所以可以想到每次删除第i条边时,我们只需要暂时把这条边长度赋值无穷大,然后对1,2,3,....n各点进行spfa然后求和,这是最初的思想,但是 看复杂度m*n*m=9*10^8肯定会超时,第一个m代表删除m条边,第二个n表示每次删除一条边后就对1,2,3....n个点进行spfa,第三个 m表示spfa的复杂度(由于边长度为1所以每个点其实只要入队一次,所以复杂度是m),在m*n*m中我们能优化的只能是第一个m了,根据上面n表示的 意思我们知道每起始个点都要因为m条边而进行spfa
m次,但是其实以起始点i开始的最短路边只有n-1,条,也就是说有m-n+1条边与以起始点i开始的最短路无关(即影响不到),那么如何去判断什么时候进行spfa呢??在这里引进一个数组flag[i][u][v]表示以点i作为起始点的最短路是否含有边u-v,所以我们要预先进行spfa来标记flag

这样就能根据flag[i][u[v]]来决定什么时候进行spfa,所以复杂度就变成了n*n*m,第一个n表示每个点最多要进行n-1(o(n))次

AC代码:

#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<string>
#include<queue>
#include<algorithm>
#include<map>
#include<iomanip>
#define INF 99999999
using namespace std;

const int MAX = 100+10;
int dist[MAX], Edgenum[MAX][MAX];
bool mark[MAX],flag[MAX][MAX][MAX];
int size,head[MAX],n,m,pos[3002],sum[MAX];
struct node
{
    int v,w;
    int next;
    node(){}
    node(int V,int W,int Next):v(V),w(W),next(Next){}
}edge[6500];

void Init(int num)
{
    memset(head, -1, sizeof(int)*(num + 2));
    memset(Edgenum, 0, sizeof Edgenum);
    memset(flag, false, sizeof(flag));
    size = 0;
}

void put_edge(int u,int v,int w)
{
    edge[size] = node(v,w,head[u]);
    head[u] = size++;
}

int spfa(int s,bool p)
{
    int ans = 0;
    queue<int>enqueue;
    for(int i = 1; i <= n; ++i)
    {
            dist[i] = INF;
            mark[i] = false;
    }
    dist[s] = 0;
    mark[s] = true;
    enqueue.push(s);
    while(!enqueue.empty())
    {
        int u = enqueue.front();
        enqueue.pop();
        mark[u] = false;
        for(int j = head[u]; j !=-1; j = edge[j].next)
        {
            int v = edge[j].v;
            if(dist[v] > dist[u] + edge[j].w)
            {
                dist[v] = dist[u] + edge[j].w;
                if(!mark[v])
                {
                    if(p)
                        flag[s][u][v] = flag[s][v][u] = true;
                    enqueue.push(v);
                    mark[v] = true;
                }
            }
        }
    }
    for(int i = 1; i <= n; ++i)
    {
        if(dist[i] == INF)
            return INF;
        else
            ans+=dist[i];
    }
    return ans;
}

int main()
{
    int ans,u,v,temp;
    while(cin >> n >> m)
    {
        Init(n);
        for(int i = 0; i < m; ++i)
        {
            cin >> u >> v;
            pos[i] = size;
            put_edge(u,v,1);
            put_edge(v,u,1);
            ++Edgenum[u][v];
            ++Edgenum[v][u];
        }
        ans = temp = 0;
        for(int i = 1; i <= n; ++i)
        {
            sum[i] = spfa(i,1);
            if(sum[i] == INF)
            {
                ans = INF;
                break;
            }
            else
                ans+=sum[i];
        }

        for(int i = 0; i < m; ++i)
        {
            u = edge[pos[i]+1].v;
            v = edge[pos[i]].v;
            int s = ans;
            if(ans == INF)
                cout << "INF" << endl;
            else if(Edgenum[u][v] - 1 > 0)
                cout << ans << endl;
            else
            {
                edge[pos[i]+1].w = INF;
                edge[pos[i]].w= INF;
                for(int j = 1; j <= n; ++j)
                {
                    if(flag[j][u][v])
                    {
                        temp = spfa(j,0);
                        if(temp == INF)
                        {
                            cout << "INF" << endl;
                            break;
                        }
                        else
                            s+=temp-sum[j];
                    }
                }
                if(temp != INF)
                    cout << s << endl;
                edge[pos[i]+1].w = 1;
                edge[pos[i]].w = 1;
            }
        }
    }
    return 0;
}


相关文章推荐

hdu 3507 斜率优化dp 入门学习

我们知道,有些DP方程可以转化成DP[i]=f[j]+x[i]的形式,其中f[j]中保存了只与j相关的量。这样的DP方程我们可以用单调队列进行优化,从而使得O(n^2)的复杂度降到O(n)。  ...

hdu 2433 Travel(spfa)

小记:这题主要还是题意需要搞懂,题目意思的SUM是指以某点出发到

算法为啥子那么难呢???俺为啥子要学算法慎??

广大码农同学们大多都有个共识,认为算法是个硬骨头,很难啃,悲剧的是啃完了还未必有用——除了面试的时候。实际工程中一般都是用现成的模块,一般只需了解算法的目的和时空复杂度即可。 不过话说回来,面试的时...

HDU2433(SPFA)

刚开始用dijkstra()+暴力枚举,然后就超时了。后来看了题解才知道这题的关键所在:用sum[i]来存以i为起点的最短路之和,ans表示i从1到n的sum[i]的和,然后摧毁道路之后,以u为起点,...

【TOJ 2433】Word Rings【SPFA+二分】

题意:给出n个字符串,字符串衔接的方式是

bzoj 2433 [Noi2011]智能车比赛 [计算几何+spfa]

Description 新一届智能车大赛在JL大学开始啦!比赛赛道可以看作是由n个矩形区域拼接而成(如下图所示),每个矩形的边都平行于坐标轴,第i个矩形区域的左下角和右上角坐标分别为(xi,1,yi,...

HDU2433 Travel BFS求最短路径树+优化

/* 1750ms 边长为1,所以用BFS求最短路 对于每一个点,做一次BFS,求出以这个点为出发点时的最短路径树的长度和它包含的边 记录长度是用于求值,记录边是用于优化。因为只有处于最短路径树上的边...

hdu2433(最短路径树)

链接:点击打开链接 题意:给出一个n个点m条边的无向图,问删除每一条边后每两个点最短路的和 代码:#include #include #include #include #include ...

hdu2433Xiao Ming climbing

Xiao Ming climbing Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Othe...

hdu 2433 TRAVEL

题意:给出边建立图 然后依次删除给出的边,求最短路,如无法连通 则返回INF 这里最短路 =  多源最短路和  即求出对于单源最短路 再for一个循环求出多源最短路  相加 用dijkst...
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:深度学习:神经网络中的前向传播和反向传播算法推导
举报原因:
原因补充:

(最多只允许输入30个字)