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


hdu1317XYZZY (SPFA处理 有环的情况)

Problem Description It has recently been discovered how to run open-source software on the Y-Crate g...
  • u010372095
  • u010372095
  • 2013年12月07日 00:08
  • 1208

ACM-最短路(SPFA,Dijkstra,Floyd)之最短路——hdu2544

ACM 最短路(SPFA,Dijkstra,Floyd) 最短路 hdu2544
  • lx417147512
  • lx417147512
  • 2014年05月27日 11:59
  • 3351

HDU - 2433 Travel (最短路树)

题目大意:有N个点,M条边,每次删掉一条边,问删掉该边后,所有点之间的最短路的和是多少解题思路:刚开始就想,删掉一次floyd一次,结果可想而之,TLE了 后来看了别人的,发现了一种叫做最短路树的东...
  • L123012013048
  • L123012013048
  • 2015年07月31日 23:57
  • 1455

HDU2433(SPFA)

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

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

题意:给出n个字符串,字符串衔接的方式是
  • u010089558
  • u010089558
  • 2014年07月27日 10:25
  • 235

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

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

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

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

hdu2433(最短路径树)

链接:点击打开链接 题意:给出一个n个点m条边的无向图,问删除每一条边后每两个点最短路的和 代码:#include #include #include #include #include ...
  • stay_accept
  • stay_accept
  • 2017年06月27日 14:21
  • 97

hdu2433Xiao Ming climbing

Xiao Ming climbing Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Othe...
  • acm_fighting
  • acm_fighting
  • 2015年09月14日 16:11
  • 220

hdu 2433 TRAVEL

题意:给出边建立图 然后依次删除给出的边,求最短路,如无法连通 则返回INF 这里最短路 =  多源最短路和  即求出对于单源最短路 再for一个循环求出多源最短路  相加 用dijkst...
  • yerongsc
  • yerongsc
  • 2013年05月05日 12:40
  • 299
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:hdu 2433 spfa
举报原因:
原因补充:

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