[切题][boj1095]dijkstra+DP


题目:http://acm.scs.bupt.cn/onlinejudge/showproblem.php?problem_id=1095
题意:这题要在一个无向正权图上找单源最短路,找到目标点后,还要求出到达这个点的最短路径的数量。有重边。
解法:dijkstra+DP。正权图找最短路首先想到dijkstra,然后考虑如何获得最短路数量和怎样处理重边。因为两点间只需一条最的路径就够了,因此记录图的时候可以考虑忽略其他权比较高的路径,只记录最短的那条。并且增加一个二元数组记录相邻点间的最短路径条数。此外有数组d记录起点到各点的最短距离,count记录到达这点的最短路径数。在dijkstra过程中,加入新节点后松弛没找到最短路的点的过程中,考虑如果松弛过程中d[i]==d[pos]+map[pos][i],则count[i]+=count[pos]*p[pos][i](此处之前错误写成了count[i]++,-_-!),如果d[i]>d[pos]+map[pos][i],则count[i]=count[pos]*p[pos][i]。最后输出d[b],count[b]就行,注意各数组初始化,并且注意是两组输出之间有空行,最后一组输出后不用空行,仅换行,这里我也悲剧了一次。
code:

#include<stdio.h>
#include<stdlib.h>
#include<memory.h>
int main()
{
	long cur,pos,temp;
	long f,m,n,i,j,x,y,l,a,b;
	long map[310][310],p[310][310],count[310],d[310],flag[310];
	scanf("%ld",&f);
	while(f--)
	{
		scanf("%ld%ld",&n,&m);
		memset(map,0,sizeof(long)*310*310);
		for(i=0;i<m;i++)
		{
			scanf("%ld%ld%ld",&x,&y,&l);
			if(map[x][y]&&map[x][y]==l)
			{
				p[x][y]++;
				p[y][x]++;
			}
			else if(map[x][y]&&map[x][y]>l)
			{
				map[x][y]=l;
				map[y][x]=l;
				p[x][y]=1;
				p[y][x]=1;
			}
			else if(!map[x][y])
			{
				map[x][y]=l;
				map[y][x]=l;
				p[x][y]=1;
				p[y][x]=1;
			}
		}
		scanf("%ld%ld",&a,&b);
		for(i=0;i<=n;i++)
		{
			flag[i]=0;
			d[i]=1000000000;
		}
		d[a]=0;
		flag[a]=1;
		cur=a;
		count[a]=1;
		for(i=1;i<=n;i++)
		{
			if(map[a][i])
			{
				d[i]=map[a][i];
				count[i]=count[a]*p[a][i];
			}
		}
		while(!flag[b])
		{
			temp=1000000000;
			pos=-1;
			for(i=1;i<=n;i++)
			{
				if(!flag[i]&&d[i]&&d[i]<temp)
				{
					temp=d[i];
					pos=i;
				}
			}
			if(pos==-1)
			break;
			flag[pos]=1;
			for(i=1;i<=n;i++)
			{
				if(!flag[i]&&i!=pos&&map[pos][i]&&d[i]==d[pos]+map[pos][i])
				{
					count[i]+=count[pos]*p[pos][i];
				}
				else if(!flag[i]&&i!=pos&&map[pos][i]&&d[i]>d[pos]+map[pos][i])
				{
					d[i]=d[pos]+map[pos][i];
					count[i]=count[pos]*p[pos][i];
				}
			}

		}
		if(flag[b])
		{
			printf("%ld %ldn",d[b],count[b]);
		}
		else
		{
			printf("Poor Javamann");
		}
		if(f!=0)
		printf("n");
	}
}
Leave a Reply

Your email address will not be published. Required fields are marked *

CodePhoto.WTF © 2025