一道usaco 的spfa 求最短路径

fx397993401 2012-10-26 09:06:10
题目http://www.nocow.cn/index.php/Translate:USACO/butter
我的代码 在本地运行要2s多,然后在网上找了一个,只要0.2s ,大牛能帮我找下我的代码慢在哪里么

/*
ID:fuxiang2
PROG: butter
LANG: C++
*/
#include <iostream>
#include <fstream>
#include <stack>
#include <string>
#include <vector>
#include <queue>
#include <map>
#include <list>
#include <algorithm>
#include <set>
#include <cmath>
#include <cstring>
#include <cstdlib>

using namespace std;
ofstream fout ("butter.out");
ifstream fin ("butter.in");


const int N = 802;
int maxN = 0x0fffffff;
int graph[N][N];
int d[N];
int cow[N];
int flag[N] ;
int n,p,c;

//bool queue_find(queue<int > q,int key)
//{
// while(!q.empty() ){
// int num = q.front();
// q.pop();
//
// if(num == key )
// return true;
// }
//
// return false;
//}
void spfa(int start)
{
queue<int > q;
q.push(start);

//初始化距离
for(int i = 1 ; i <= p ; i ++)
d[i] = maxN;
d[start] = 0;

memset(flag,N*sizeof(int),0);

flag[start] = 1;
while(!q.empty()){

int u = q.front();
q.pop();

flag[u] = 0;
for(int v = 1 ; v <= p ; v ++){
//if(u != v && graph[u][v] ){
if( d[v] > graph[u][v] + d[u] ){
d[v] = graph[u][v] + d[u];

//if(queue_find(q ,v) == false){
if( flag[v] == 0){
q.push(v);
flag[v] = 1;
}
}

// }// end if
}//end for
}//end while



}
int main()
{
fin>>n>>p>>c;
for(int i = 1; i <= n ; i ++){
int a;
fin>>a;
cow[a] ++;
}
// for(int i =1 ; i < N ; i ++){
// for(int j = 1 ; j < N ; j ++)
// graph[i][j] = maxN;
// }

for(int i = 1 ; i <= c ; i ++){
int x,y,w;
fin>> x>>y >>w;
graph[x][y] = graph[y][x] = w;
}

long minN = maxN;

for(int i = 1 ; i <= p ; i ++){
spfa(i);
long t = 0;
for(int j = 1 ; j <= p ; j ++){
if (d[j] == maxN) {
t = maxN;
break;
}
t += cow[j]*d[j];
}

if (t < minN) minN = t;


}

fout<< minN <<endl;
return 0;
}



0.2s的代码

#include<fstream>
#include<cstring>
#include<queue>
using namespace std;
const int MAX=805;
const int INF=0x0fffffff;
ifstream fin("butter.in");
ofstream fout("butter.out");
struct node{
int end,len;
};
int cnt[MAX]={0},location[505]={0},n,p,c;
node adj[MAX][MAX];
bool in[MAX]={0};
int d[MAX];
int SPFA(int i)
{
memset(in,0,sizeof in);
for(int k=1; k<=p; k++)d[k]=INF;
queue<int> Q;
Q.push(i);
in[i]=true;
d[i]=0;
while(!Q.empty())
{
int x=Q.front(); Q.pop();
in[x]=false;
for(int j=0; j<cnt[x]; j++)
if(d[x]+adj[x][j].len < d[ adj[x][j].end ])
{
d[adj[x][j].end]=d[x]+adj[x][j].len;
if(!in[adj[x][j].end])
{
Q.push(adj[x][j].end);
in[adj[x][j].end ]=true;
}
}
}

int ans=0;

for(int j=1; j<=n; j++)
{
if(d[location[j]]==INF)return -1;
else ans+=d[location[j]];
}
return ans;
}

void print()
{
int i,j;
for(i=1; i<=p ; i++)
for(j=0; j<cnt[i]; j++)
{
fout<<i<<' '<<adj[i][j].end<<' '<<adj[i][j].len<<endl;
}
}

int main()
{
memset(cnt,0,sizeof cnt);
fin>>n>>p>>c;
for(int i=1; i<=n; i++)
fin>>location[i];

for(int i=1,s,t,value; i<=c; i++)
{
fin>>s>>t>>value;
adj[s][cnt[s]].end=t; adj[s][cnt[s]].len=value; cnt[s]++;
adj[t][cnt[t]].end=s; adj[t][cnt[t]].len=value; cnt[t]++;
}

int tt,min=INF;

for(int i=1; i<=p; i++)
{
tt=SPFA(i);
if(tt<min&&tt!=-1) min=tt;
}
fout<<min<<endl;
//system("pause");
return 0;
}
...全文
153 3 打赏 收藏 转发到动态 举报
AI 作业
写回复
用AI写文章
3 条回复
切换为时间正序
请发表友善的回复…
发表回复
fx397993401 2012-10-31
  • 打赏
  • 举报
回复
[Quote=引用 2 楼 的回复:]

usaco的号忘了。。。大概看一下吧
你的图是用邻接矩阵存的,下面那个是用邻接表存的。所以且不论枚举临边的速度,你为什么要把初始化graph的步骤注释了呢
另外
C/C++ code
memset(flag,N*sizeof(int),0);

这么写真的没问题么

至于queue的效率倒没什么太大问题吧
[/Quote]

谢谢 确实 最后用临接表存 就过了
Prairial_0 2012-10-27
  • 打赏
  • 举报
回复
usaco的号忘了。。。大概看一下吧
你的图是用邻接矩阵存的,下面那个是用邻接表存的。所以且不论枚举临边的速度,你为什么要把初始化graph的步骤注释了呢
另外
memset(flag,N*sizeof(int),0);

这么写真的没问题么

至于queue的效率倒没什么太大问题吧
FancyMouse 2012-10-27
  • 打赏
  • 举报
回复
gcc那个STL的queue是慢。我一般STL只用vector,set和map。vector速度没问题。set和map看重的是功能不是速度。queue和stack……自己写吧

33,027

社区成员

发帖
与我相关
我的任务
社区描述
数据结构与算法相关内容讨论专区
社区管理员
  • 数据结构与算法社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧