[U]3.2.6 Sweet Butter 枚举+SPFA

赤裸裸的SPFA模板题... 有点小失误,变量弄错了... 囧~

枚举集合点,A之~ 原来用的Floyd结果超时了....

/*
ID:bysen
LANG:C++
PROG:butter
*/
#include<stdio.h>
#include<queue>
#define INF 0x7FFFFFFF
#define MAXP 801
#define MAXC 1500
using namespace std;

struct Edge
{
 	   int v,len;
 	   Edge *next;
}edge[MAXC<<1],*ptr[MAXP];

int dist[MAXP];
int cow[MAXP];
int EdgeNum;
int N,P,C;
int ans;
 	
void addEdge( int u,int v,int len )
{
 	 Edge *p=&edge[EdgeNum++];
 	 p->v=v;
 	 p->len=len;
 	 p->next=ptr[u];
 	 ptr[u]=p;
}

void init()
{
 	ans=INF;
 	scanf( "%d %d %d",&N,&P,&C );
 	for( int i=1;i<=N;i++ )
 		 scanf( "%d",&cow[i] );
 	
	EdgeNum=0;
	for( int i=1;i<=C;i++ )
    {
	 	 int u,v,len;
	 	 scanf( "%d %d %d",&u,&v,&len );
	 	 addEdge( u,v,len );
	 	 addEdge( v,u,len );
    }
}

void spfa( int start )
{
 	 int dist[MAXP];
	 queue<int> myQueue;
	 bool inQ[MAXP]={false};
	 
 	 for( int i=0;i<MAXP;i++ )
 	 	  dist[i]=INF;
	 while( !myQueue.empty() )myQueue.pop();
	 myQueue.push(start);
	 inQ[start]=true;
	 dist[start]=0;
	 
	 while( !myQueue.empty() )
	 {
	  		int cur=myQueue.front();
	  		myQueue.pop();
	  		inQ[cur]=false;
	  		Edge *p=ptr[cur];
	  		while( p )
	  		{
			 	   if( dist[p->v]>dist[cur]+p->len )
			 	   {
				   	   dist[p->v]=dist[cur]+p->len;
				   	   if( inQ[p->v]==false )
				   	   {
					   	   inQ[p->v]=true;
					   	   myQueue.push(p->v);
	   				   }
				   }
			 	   p=p->next;
 	        }
     }
     int sum=0;
     for( int i=1;i<=N;i++ )
     {
     	  sum+=dist[cow[i]];
     	  //printf( "%d %d: %d\n",start,cow[i],dist[cow[i]] );
     }
     //printf( "%d\n",sum );
     //printf( "----------------\n" );
  	 if( ans>sum )
  	 	 ans=sum;
}

int main()
{ 
  	freopen( "butter.in","r",stdin );
  	freopen( "butter.out","w",stdout );
  	init();
  	for( int i=1;i<=P;i++ )
    	 spfa(i);//enum the start
 	printf( "%d\n",ans );
}


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值