hdu 2433 spfa
来源:互联网 发布:箪食壶浆以迎将军者乎 编辑:程序博客网 时间:2024/06/10 20:25
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
题目是要求每次删除地i条边后以1,2,3,...n为起始点到其他点的最短路和的总和
分析:从题意可以想到用spfa,毕竟spfa是求单源多点的最短路的好算法, 所以可以想到每次删除第i条边时,我们只需要暂时把这条边长度赋值无穷大,然后对1,2,3,....n各点进行spfa然后求和,这是最初的思想,但是 看复杂度m*n*m=9*10^8肯定会超时,第一个m代表删除m条边,第二个n表示每次删除一条边后就对1,2,3....n个点进行spfa,第三个 m表示spfa的复杂度(由于边长度为1所以每个点其实只要入队一次,所以复杂度是m),在m*n*m中我们能优化的只能是第一个m了,根据上面n表示的 意思我们知道每起始个点都要因为m条边而进行spfa
m次,但是其实以起始点i开始的最短路边只有n-1,条,也就是说有m-n+1条边与以起始点i开始的最短路无关(即影响不到),那么如何去判断什么时候进行spfa呢??在这里引进一个数组flag[i][u][v]表示以点i作为起始点的最短路是否含有边u-v,所以我们要预先进行spfa来标记flag
这样就能根据flag[i][u[v]]来决定什么时候进行spfa,所以复杂度就变成了n*n*m,第一个n表示每个点最多要进行n-1(o(n))次
AC代码:
#include<iostream>#include<cstdio>#include<cstdlib>#include<cstring>#include<string>#include<queue>#include<algorithm>#include<map>#include<iomanip>#define INF 99999999using namespace std;const int MAX = 100+10;int dist[MAX], Edgenum[MAX][MAX];bool mark[MAX],flag[MAX][MAX][MAX];int size,head[MAX],n,m,pos[3002],sum[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(head, -1, sizeof(int)*(num + 2)); memset(Edgenum, 0, sizeof Edgenum); memset(flag, false, sizeof(flag)); size = 0;}void put_edge(int u,int v,int w){ edge[size] = node(v,w,head[u]); head[u] = size++;}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;}
- hdu 2433 spfa
- hdu 2433 Travel(spfa)
- hdu 1596(SPFA)
- SPFA首题!hdu-2544
- hdu-1874 SPFA
- hdu 2544 spfa 模板
- hdu 1874 (spfa)
- HDU 2544 (SPFA)
- hdu 4396 spfa
- HDU 4294 spfa
- HDU 3416 spfa + dinic
- hdu 2544(spfa)
- HDU 4568 SPFA + TSP
- HDU 4571 SPFA+DP
- HDU 2962(SPFA+二分)
- hdu 1874 (spfa)
- 【spfa】 hdu 2680
- hdu 1535 spfa
- 实现咕咚地图路径颜色根据速度不同而颜色不同
- 同一服务器部署多个tomcat时的端口号修改详情
- Unix/Linux系统下的高级C编程的主要内容1、20160531
- SharedPreferences保持对象数据
- 一个简单的MemoryCache的实现
- hdu 2433 spfa
- Android加载图片你必须知道的技巧
- 理解Docker跨多主机容器网络
- 当使用apm遇到问题时常用的apm命令
- hiho第七周 完全背包
- C++ 中的关键字explicit
- java面向对象编程学习日志【1】第一章
- New package not yet registered with the system 解决方法
- iOS学习之——GCD(Grand Central Dispatch)