HDU3191(次短路)

解题思路:这是我从打ACM起做的心态最炸裂的一道题。一开始用A*求K短路写,超内存。然后就老老实实用次短路来写,但为什么我会在这么简单的一道略水的题上卡了半天啊。。。。。可能是我平时一直记忆的模板有问题吧。为什么优先队列中距离相等时,要按标号的顺序排列这一点,我到现在都还是云里雾里的,算了,抽时间换个更加明了的写法吧。

#include<cstdio>
#include<cstring>
#include<iostream>
#include<queue>
#include<algorithm>
#define inf 0x3f3f3f3f
using namespace std;
int map[60][60];
int dis1[60],dis2[60]; 
int n,m,s,e;
struct node
{
	int f,v,d;
	node(){}
	node(int f,int v,int d):f(f),v(v),d(d){}
}p;
bool operator<(node a,node b)
{
	if(a.d!=b.d)
	return a.d>b.d;
	return a.v>b.v;%不按顺序排列就错 
}
priority_queue<node>q;
int record[3][60],vis[3][60];
void djk()
{
	int v,f;
	node p1;
	while(!q.empty()) q.pop();
	memset(record,0,sizeof(record));
	memset(vis,0,sizeof(vis));
	q.push(node(0,s,0));
	fill(dis1,dis1+n,inf);
	fill(dis2,dis2+n,inf);
	dis1[s]=0;
	record[0][s]=1;
	while(!q.empty())
	{
		p1=q.top();
		v=p1.v;f=p1.f;
		q.pop();
		if(vis[f][v]) continue;
		vis[f][v]=1;
		for(int i=0;i<n;i++)
		{
			//cout<<i<<endl;
			if(map[v][i]!=inf&&i!=v)
			{
				if(!vis[0][i]&&p1.d+map[v][i]<dis1[i])
				{
					if(dis1[i]!=inf)
					{
						dis2[i]=dis1[i];
						record[1][i]=record[0][i];
						q.push(node(1,i,dis2[i]));
					}
					dis1[i]=p1.d+map[v][i];
					record[0][i]=record[f][v];
					q.push(node(0,i,dis1[i]));
				}else
				if(!vis[0][i]&&p1.d+map[v][i]==dis1[i])
				{
					dis1[i]=p1.d+map[v][i];
					record[0][i]+=record[f][v];
				}else
				if(!vis[1][i]&&p1.d+map[v][i]<dis2[i])
				{
					dis2[i]=p1.d+map[v][i];
					record[1][i]=record[f][v];
					q.push(node(1,i,dis2[i]));
				}else
				if(!vis[1][i]&&p1.d+map[v][i]==dis2[i])
				{
					record[1][i]+=record[f][v];
				}
				
			}
		}
	}
	printf("%d %d\n",dis2[e],record[1][e]);
}
int main()
{
	//freopen("t.txt","r",stdin);
	int x,y,w;
	while(scanf("%d%d%d%d",&n,&m,&s,&e)!=EOF)
	{
		fill(map[0],map[0]+60*60,inf);	
		while(m--)
		{
			scanf("%d%d%d",&x,&y,&w);
			map[x][y]=w;
		}
		djk();
	}
	return 0;
} 

 

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值