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



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