Silver Cow Party POJ 3268 SPFA
这个题我是这么做的,本来想用Floyd写,但是看到n<=1000,这样的话时间复杂度就有10^9,一看讨论版,说超时,我果断放弃。边只有100000,SPFA的时间复杂度好像只有O(m),然后分析一下这个题发现,只需找从X农场到其余农场的最小时间就行(来和去)。那么从X农场去其余农场的最短时间,相当于其余各个农场的奶牛从X农场回去的最短时间,把所有方向都翻转,再求一遍从X农场去其余农场的最短时间就变成各个农场的奶牛来X农场的最短时间,这样用两次SPFA就行,是吧。
然后为了实现我所说的,我耗费了很多存储空间,唉,结果时间也不是很快,那些0ms的到底是怎么写出来的啊。。。。。
而且我还用到了三维数组,我自己看的也不是很习惯,但是多看几眼就习惯了的,我以后会尽量不用三维数组的
贴代码:
View Code
1 #include <cstdio> 2 #include <queue> 3 #include <cstring> 4 #define MAXN 1005 5 #define INF 1000000 6 using namespace std; 7 int n; 8 int num[2][MAXN]; 9 int time[2][MAXN]; 10 bool s[MAXN]; 11 struct ArcNode 12 { 13 int v,w; 14 } edge[2][MAXN][MAXN]; 15 void SPFA(int vo,int ser) 16 { 17 int i,j; 18 queue<int> Q; 19 memset(s,false,sizeof(s)); 20 for(i = 1; i<=n; i++) 21 time[ser][i] = INF; 22 time[ser][vo] = 0; 23 Q.push(vo); 24 s[vo] = true; 25 while(!Q.empty()) 26 { 27 int t = Q.front(); 28 Q.pop(); 29 s[t] = false; 30 for(j=0; j<num[ser][t]; j++) 31 { 32 if(time[ser][t] + edge[ser][t][j].w < time[ser][edge[ser][t][j].v]) 33 { 34 time[ser][edge[ser][t][j].v] = time[ser][t] + edge[ser][t][j].w; 35 if(!s[edge[ser][t][j].v]) 36 { 37 Q.push(edge[ser][t][j].v); 38 s[edge[ser][t][j].v] = true; 39 } 40 } 41 } 42 } 43 } 44 int main() 45 { 46 // freopen("in.cpp","r",stdin); 47 int m,x; 48 while(~scanf("%d%d%d",&n,&m,&x)) 49 { 50 int i,j; 51 memset(num,0,sizeof(num)); 52 for(i=0; i<m; i++) 53 { 54 int u,v,w; 55 scanf("%d%d%d",&u,&v,&w); 56 edge[0][u][num[0][u]].w = w; 57 edge[0][u][num[0][u]].v = v; 58 num[0][u]++; 59 edge[1][v][num[1][v]].w = w; 60 edge[1][v][num[1][v]].v = u; 61 num[1][v]++; 62 } 63 SPFA(x,0); 64 SPFA(x,1); 65 int max = -1; 66 for(i=1; i<=n; i++) 67 if(time[0][i] + time[1][i] > max) 68 max = time[0][i] + time[1][i]; 69 printf("%d\n",max); 70 } 71 }
很久之后,我重新看了这个题,感觉自己好搓,用三维数组,太搓,所以,我重新写了下面的代码:
1 //#define debug 2 #include <cstdio> 3 #include <cstring> 4 #include <queue> 5 #include <vector> 6 #define N 1005 7 #define INF 0x3f3f3f3f 8 using namespace std; 9 int n; 10 struct arc 11 { 12 int v,w; 13 }; 14 vector<arc> ve1[N],ve2[N]; 15 int dist1[N],dist2[N]; 16 void spfa(int src,int dist[],vector<arc> ve[]) 17 { 18 int i,u; 19 queue<int> qu; 20 bool vis[N]; 21 for(int i=1; i<=n; ++i) 22 { 23 vis[i] = 0; 24 dist[i] = INF; 25 } 26 dist[src] = 0; 27 vis[src] = 1; 28 qu.push(src); 29 while(!qu.empty()) 30 { 31 u = qu.front(); 32 qu.pop(); 33 vis[u] = 0; 34 for(int i=0; i<ve[u].size(); ++i) 35 { 36 int v = ve[u][i].v; 37 if(dist[v] > dist[u] + ve[u][i].w ) 38 { 39 dist[v] = dist[u] + ve[u][i].w ; 40 if(!vis[v]) 41 { 42 qu.push(v); 43 vis[v] = 1; 44 } 45 } 46 } 47 } 48 } 49 int main() 50 { 51 #ifdef debug 52 freopen("in.c","r",stdin); 53 #endif 54 int m,x; 55 scanf("%d%d%d",&n,&m,&x); 56 while(m--) 57 { 58 int u,v,w; 59 scanf("%d%d%d",&u,&v,&w); 60 arc t; 61 t.v = v; 62 t.w = w; 63 ve1[u].push_back(t); 64 t.v = u; 65 ve2[v].push_back(t); 66 } 67 spfa(x,dist1,ve1); 68 spfa(x,dist2,ve2); 69 int ans = -INF; 70 for(int i=1; i<=n; ++i) 71 { 72 if(dist1[i] + dist2[i] > ans) 73 ans = dist1[i] + dist2[i] ; 74 } 75 printf("%d\n",ans); 76 return 0; 77 }
这个代码用的是vector做邻接表,所以速度慢一下····捂脸·····
然后出现了一件神奇的事情,我把上面的代码用codeblocks10.05编译了一下,编译通不过·····可能是关键字冲突一类的·····这说明了codeblocks再与时俱进的同时,我们命名时要注意啊····