雕刻时光

just do it……nothing impossible
  博客园  :: 首页  :: 新随笔  :: 联系 :: 订阅 订阅  :: 管理

USACO3.2.6多源最短路径和SPFA实现

Posted on 2011-02-15 21:52  huhuuu  阅读(739)  评论(0编辑  收藏  举报
枚举起点n,用SPFA求最短路,然后求和,算出路径和最小点即可
View Code
#include<iostream>
#include
<queue>
using namespace std;
const int maxn=99999999;
const int edge_maxn = 3000;
const int point_maxn = 805;
int m,cown,mina;
struct node
{
int v;
int w;
int next;
}edge[edge_maxn];
int pre[point_maxn];
int n;

queue
<int>Q;
int dirs[point_maxn],cow[edge_maxn];
bool vis[point_maxn];
void Init()
{
memset(pre,
-1,sizeof(pre));
memset(cow,
0,sizeof(cow));
int x,y,z,temp;
int index=1;
int i;
for(i=1;i<=cown;i++)
{
scanf(
"%d",&temp);
cow[temp]
++;
}
for(i=1;i<=m;i++)
{
scanf(
"%d%d%d",&x,&y,&z);
edge[index].v
=y;
edge[index].w
=z;
edge[index].next
=pre[x];
pre[x]
=index++;
swap(x,y);
edge[index].v
=y;
edge[index].w
=z;
edge[index].next
=pre[x];
pre[x]
=index++;
}
}
void SPFA(int mu)
{
int start,i;
start
=mu;
while(!Q.empty())
{
Q.pop();
}
memset(vis,
0,sizeof(vis));
//fill(dirs,dirs+point_maxn,maxn);
for(i=1;i<=n;i++)
dirs[i]
=99999999;
dirs[start]
=0;
vis[start]
=1;
Q.push(start);
while(!Q.empty())
{
int top=Q.front();
Q.pop();
vis[top]
=0;
for(int j=pre[top];j!=-1;j=edge[j].next)
{
int e=edge[j].v;
if(dirs[e]>edge[j].w+dirs[top])
{
dirs[e]
=edge[j].w+dirs[top];
if(!vis[e])
{
Q.push(e);
vis[e]
=1;
}
}
}
}
int add=0;
for(i=1;i<=n;i++)
{
if(start!=i)
add
+=cow[i]*dirs[i];
}
if(mina>add)
mina
=add;
}
int main()
{
int i;
while(scanf("%d%d%d",&cown,&n,&m)!=EOF && (n!=0 || m!=0))
{
mina
=9999999;
Init();
for(i=1;i<=n;i++)
{
SPFA(i);
}
printf(
"%d\n",mina);
}
return 0;
}