现在的位置: 首页 > 综合 > 正文

ZOJ 2526(最短路+优先队列)

2018年01月14日 ⁄ 综合 ⁄ 共 2350字 ⁄ 字号 评论关闭

题意:求出一个图的最短路的数量,并求出在最短路的条件下求出获得权值最大的路。

我的做法就是用优先队列优化Dijkstra算法,就是在mindis[v]>mindis[number]+dis[i](i是边的编号,v是边的终点,number是边的始点),或者在mindis[v]==mindis[number]+dis[i]的条件下maxcost[v]<num[v]+maxcost[number]就需要松弛。

但是由于对优先队列的使用不是非常熟悉,于是自己坑了自己,在重载<运算符的时候,搞错了,于是WA了一天。

#include<iostream>  
#include<vector>  
#include<algorithm>  
#include<cstdio>  
#include<queue>  
#include<stack>  
#include<string>  
#include<map>  
#include<set>  
#include<cmath>  
#include<cassert>  
#include<cstring>  
#include<iomanip>  
#include<ctime>  
#include<climits>
using namespace std;  

int pre[505];
int num[505];
int vv[26000],fir[505],nxt[26000],dis[26000];
int maxcost[505],mindis[505];
bool vis[505];
int e;
struct Pnt
{
	int mindis,num;
	Pnt(int mindis,int num)
	{
		this->mindis=mindis;
		this->num=num;
	}
	Pnt(){}
	bool operator <(const Pnt& b)const
	{
		return mindis>b.mindis;
	}
};
void add(int u,int v,int cost)
{
	dis[e]=cost;
	vv[e]=v;
	nxt[e]=fir[u];
	fir[u]=e++;
}
priority_queue<Pnt>que;
vector<int>vec;
int dfs(int sta,int end,int len)
{
	vis[sta]=1;
	int res=0;
	if(sta==end&&!len) res=1;
	else if(len<0) res=0;
	else 
	{
		
		for(int i=fir[sta];i!=-1;i=nxt[i])
		{
			if(!vis[vv[i]])
				res+=dfs(vv[i],end,len-dis[i]);
		}
	}
	vis[sta]=0;
	return res;
}
int main()
{ 
	int n,m,r1,r2;
	while(scanf("%d%d%d%d",&n,&m,&r1,&r2)!=EOF)
	{
		vec.clear();
		e=0;
		memset(pre,-1,sizeof(pre));
		memset(fir,-1,sizeof(fir));
		memset(vis,0,sizeof(vis));
		memset(maxcost,-1,sizeof(maxcost));
		for(int i=0;i<n;i++)
		{
			scanf("%d",&num[i]);
			mindis[i]=INT_MAX;
		}
		int u,v,cost;
		for(int i=0;i<m;i++)
		{
			scanf("%d%d%d",&u,&v,&cost);
			add(u,v,cost);
			add(v,u,cost);
		}
		while(!que.empty()) que.pop();
		maxcost[r1]=num[r1];
		mindis[r1]=0;
		que.push(Pnt(0,r1));
		while(!que.empty())
		{
			Pnt top=que.top();
			que.pop();
			int number=top.num;
			//cout<<"number="<<number<<endl;
			if(vis[number]) continue;
			vis[number]=1;
			for(int i=fir[number];i!=-1;i=nxt[i])
			{
				int v=vv[i];
				//cout<<"v="<<v<<" (number="<<number<<")"<<endl;
				if(mindis[v]>mindis[number]+dis[i])
				{
					mindis[v]=mindis[number]+dis[i];
					pre[v]=number;
					maxcost[v]=maxcost[number]+num[v];
					que.push(Pnt(mindis[v],v));
				}
				else if(mindis[v]==mindis[number]+dis[i]&&maxcost[v]<num[v]+maxcost[number])
				{
					pre[v]=number;
					maxcost[v]=maxcost[number]+num[v];
					que.push(Pnt(mindis[v],v));
				}
			}
		}
		memset(vis,0,sizeof(vis));
		//count the number
		printf("%d %d\n",dfs(r1,r2,mindis[r2]),maxcost[r2]);
		//get the route
		int tem=r2;
		while(tem!=r1)
		{
			//cout<<"bad\n";
			vec.push_back(tem);
			tem=pre[tem];
		}
		vec.push_back(r1);
		int size=vec.size();
		printf("%d",vec[size-1]);
		for(int i=size-2;i>=0;i--)
		{
			printf(" %d",vec[i]);
		}
		printf("\n");
	}
	return 0;  
}  





抱歉!评论已关闭.