POJ 1511 邻接表加spfa,刚开始未用邻接表构图,然后TLE到死啊、、、、、、

本文介绍了一种解决最短路径问题的有效算法——SPFA(Shortest Path Faster Algorithm),并提供了详细的实现步骤与代码示例。通过构造正向与反向图的方式,SPFA能够高效地处理带权有向图中的最短路径问题。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

http://poj.org/problem?id=1511

题目大意:一群人从七点出发到各个点的花费,是一副有向图,可以构造正向与反向两幅图,然后用spfa加邻接表、、接下来几天我得给floyd、bellmanford 、dijkstra、spfa好好做个总结。

#include<cstdio>
#include<cstring>
#include<queue>
using namespace std;
#define ll __int64
#define inf 4000000000


struct edge{
	ll next;
	ll to;
	ll side;
	
};
edge e[1000002],e1[1000002];
ll p1[1000002], p2[1000002];
ll head[1000002], tot,tot1,head1[1000002];
int k[1000002];

void add(ll a, ll b, ll c)
{
	e[tot].to=b;
	e[tot].side=c;
	e[tot].next=head[a];
//	printf("e[%I64d]=head1[%I64d]=%I64d ",tot,a,head[a]);//把输入的各项值保存下来其实这边add与add1其实只要一个就行,
//	printf("%I64d",a);
	head[a]=tot++;
//	printf("head[%I64d]=%I64d",a,tot);
 //   printf("\n");
	
}
void add1(ll a, ll b, ll c)
{


    e1[tot1].to=b;
	e1[tot1].side=c;
	e1[tot1].next=head1[a];
//	printf("%I64d\n",head1[a]);
//	printf("e1[%I64d]=head1[%I64d] ",tot1,a,head1[a]);
	head1[a]=tot1++;
//	printf("head1[%I64d]=%I64d",a,tot1-1);
  //  printf("\n");

}



int main()
{
	ll N;
	scanf("%I64d",&N);
	
	ll i,j;
	
	for(i=1;i<=N;i++)
	{
		ll P,Q;
		tot=0;
			tot1=0;
		
		scanf("%I64d%I64d",&P,&Q);
		for(j=1;j<=P;j++)
		{
			//e[j].side=inf;
			head[j]= -1;
			head1[j]=-1;
		}
	//	printf("%I64d\n",head[1]);
		for(j=1;j<=Q;j++)
		{
			ll a,b,c;
			scanf("%I64d%I64d%I64d",&a,&b,&c);
			add(a,b,c);
			add1(b,a,c);
			
		}
		for(j=1;j<=P;j++)
		{
			p1[j]=inf;
			p2[j]=inf;
			k[j]=0;
		}
		
		p1[1]=0;
		p2[1]=0;
		
		queue<ll> q;//队列
		q.push(1); //放入起始点
		while(!q.empty())
		{
			int t;
			t=q.front();
			q.pop();
			k[t]=0;
			for(j=head[t];j!=-1;j=e[j].next)
			{
				ll p=e[j].to;								
				if(p1[p]>p1[t]+e[j].side)
				{
					p1[p]=p1[t]+e[j].side;
					if(k[p]==0)
					{
						q.push(p);
						k[p]=1;
					}
				}
				
			}
		}
		//while(!q.empty())
          //        q.pop();
		//	printf("%I64d",p1[P-1]);
		q.push(1);
		for(j=1;j<=P;j++)				
			k[j]=0;


		while(!q.empty())
		{
			int t;
			t=q.front();
			q.pop();
			k[t]=0;
			for(j=head1[t];j!=-1;j=e1[j].next)
			{//printf("123");
				ll p=e1[j].to;
				if(p2[p]>p2[t]+e1[j].side)
				{
					p2[p]=p2[t]+e1[j].side;
					if(k[p]==0)
					{
						q.push(p);
						k[p]=1;
					}
				}
				
			}
		
		}		
		ll  sum=0;
			for(j=2;j<=P;j++)	
				sum+=p1[j]+p2[j];
	    	printf("%I64d\n",sum);

	}
	return 0;
}



/*
1
2 2
1 2 13
2 1 33
1
4 6
1 2 10
2 1 60
1 3 20
3 4 10
2 4 5
4 1 50
*/


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值