hdu 2433 Travel(spfa)

小记:这题主要还是题意需要搞懂,算法稍微想想还是能出来的。


题意:题目意思的SUM是指以某点出发到其它点的最短路的和,就是该点的SUM值,然后答案要的是所有的SUM值的和。


思路:我用的是最简单的方法,与discuss里的那位如出一辙。

对每点spfa一下,然后存下该点的spfa最短路的每条路,最后spfa返回该点到所有点的最短路的总和。这是spfa的工作。当然不能到所有点就返回个特殊值

然后我们记下总共的SUM值(假设为ans)。接下来就开始处理每一个输入边

首先看这条边是不是有几个,有几个的话,就输出ans。因为删掉一条也没影响。

否则,那么这条删去,就会影响结果,那么我们就一个一个的再去判断,这条边是否影响了某点的SUM值,因为SUM组成的边我们存下来了。

所以,我们只要先判断一下,这条边是否属于组成SUM的边,不是的就再spfa一遍,否则就没必要spfa了。直接下一个点

这之间我们将结果保存下来,而如果有某一点不能到达所有其它点,那么就输出INF。 


这样便可。



代码:

#include <iostream>
#include <stdio.h>
#include <string.h>
#include <math.h>
#include <stdlib.h>
#include <map>
#include <set>
#include <vector>
#include <stack>
#include <queue>
#include <algorithm>
#include <string>

using namespace std;

#define mst(a,b) memset(a,b,sizeof(a))
#define REP(a,b,c) for(int a = b; a < c; ++a)
#define eps 10e-8

const int MAX_ = 101;
const int N = 100010;
const int INF = 0x7fffffff;

int n;

struct node{
    int s, t;
}p[MAX_*30];

int g[MAX_][MAX_];
int d[MAX_], tmp[MAX_];
bool vis[MAX_],  a[MAX_][MAX_][MAX_];
int path[MAX_][MAX_];
int m, cnt;

int spfa(int start, bool flag)
{
    queue<int > q;
    REP(i, 0, n+1){
        vis[i] = 0;
        d[i] = INF;
    }
    vis[start] = 1;
    d[start] = 0;
    q.push(start);

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

        vis[cur] = 0;

        REP(i, 1, n+1){
            if(g[cur][i]  && d[i] > d[cur] + 1){

                d[i] = d[cur] + 1;
                if(flag)a[start][cur][i] = a[start][i][cur] = true;
                //path[start][i] = cur;
                if(!vis[i]){
                    vis[i] = 1;
                    q.push(i);
                    
                }
            }
        }
    }
    int ans = 0;
    REP(i, 1, n+1){
        if(d[i] == INF){ans = INF;break;}
        ans += d[i];
    }
    return ans;
}


int main(){
	int T, ss, tt, v;
	char str[10];
	//scanf("%d", &T);

	while(~scanf("%d%d", &n, &m)){

        mst(g, 0);
        mst(a, 0);
        mst(tmp, 0);

        REP(i, 0, m){
            scanf("%d%d", &p[i].s, &p[i].t);
            g[p[i].s][p[i].t] ++; g[p[i].t][p[i].s]++;
        }
/*
        REP(i, 0, n)REP(j, 0, n){
            printf("%.3f ", g[i][j]);
            if(j == n-1)printf("\n");
        }*/
        int ans = 0, tan = 0;
        REP(j, 1, n+1){

            tmp[j] = spfa(j, true);
            if(tmp[j] == INF){ans = INF; break;}
            ans += tmp[j];
        }
        //printf("ans=%d\n", ans);



        REP(i, 0, m){
            int num = ans, temp = 0;
            if(ans == INF){printf("INF\n");continue;}
            else if(g[p[i].s][p[i].t] > 1){printf("%d\n", ans);continue;}

                //int x = g[p[i].s][p[i].t] = g[p[i].t][p[i].s];
                g[p[i].s][p[i].t] = g[p[i].t][p[i].s] = 0;
                REP(j, 1, n+1){
                     if(a[j][p[i].s][p[i].t]){
                         temp = spfa(j, false);
                         if(temp == INF){break;}
                         else num += temp - tmp[j];
                     }
                }
                if(temp == INF){printf("INF\n");}
                else printf("%d\n", num);

                g[p[i].s][p[i].t] = g[p[i].t][p[i].s] = 1;

        }

	}
	return 0;
}



發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章