小記:這題主要還是題意需要搞懂,算法稍微想想還是能出來的。
題意:題目意思的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;
}