# hdu 2433 spfa

115人阅读 评论(0)

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

m次,但是其实以起始点i开始的最短路边只有n-1,条,也就是说有m-n+1条边与以起始点i开始的最短路无关(即影响不到),那么如何去判断什么时候进行spfa呢??在这里引进一个数组flag[i][u][v]表示以点i作为起始点的最短路是否含有边u-v,所以我们要预先进行spfa来标记flag

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];
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(Edgenum, 0, sizeof Edgenum);
memset(flag, false, sizeof(flag));
size = 0;
}

void put_edge(int u,int v,int w)
{
}

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

0
0

* 以上用户言论只代表其个人观点，不代表CSDN网站的观点或立场
个人资料
• 访问：13820次
• 积分：1194
• 等级：
• 排名：千里之外
• 原创：108篇
• 转载：19篇
• 译文：0篇
• 评论：0条
评论排行