小记:这题主要还是题意需要搞懂,算法稍微想想还是能出来的。
题意:题目意思的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;
}