poj-3463 Sightseeing

原创 2015年07月06日 21:02:28

题意:
给出一个n点m边的有向图,求s到t的最短路和长度为最短路+1的路的种类数;

n<=1000,m<=10000;


题解:

对于长度仅为最短路+1的路,处理时我们可以放宽一些限制;

只需求最短路和次短路,然后判断一下次短路是否满足情况就好了;

那么,求最短路+次短路的算法就用dij来处理;

令:

dis[x][k]表示x点的最短路次短路长度;

cnt[x][k]表示x点的最短路次短路分别的种类数;

vis[x][k]表示在dij算法中已经固定了的点,不会再次被更新;

k∈{0,1},分别表示最短路和次短路;

然后每次找出所以路中最小的一个,更新所有可到达的点;

分情况讨论累计种类数,就可以得到答案了;


HINT:

1.实际上dij时因为n较小,用heap实现也是可以的,但是代码比较麻烦,所以直接枚举O(n^2)

2.至于用dij而不用spfa是因为dij算法每个结点只会对其它结点进行一次更新;

   spfa可能多次入队多次更新造成计数错误,但是记录一些东西也是可以做的;

3.dij的循环要执行2*n次因为有2*n个vis数组要更新;


代码:


#include<vector>
#include<stdio.h>
#include<string.h>
#include<algorithm>
#define N 1100
using namespace std;
vector<int>to[N], val[N];
int dis[N][2], cnt[N][2];
int vis[N][2];
void init(int n)
{
	for (int i = 1; i <= n; i++)
		to[i].clear(),
		val[i].clear();
	memset(vis, 0, sizeof(vis));
	memset(cnt, 0, sizeof(cnt));
	memset(dis, 0x3f, sizeof(dis));
}
void Dij(int n)
{
	int s, t, i, j, k, x, y;
	bool fl;
	scanf("%d%d", &s, &t);
	dis[s][0] = 0;
	cnt[s][0] = 1;
	for (i = 1; i <= 2 * n; i++)
	{
		k = 0x3f3f3f3f;
		for (j = 1; j <= n; j++)
		{
			if (!vis[j][0] && dis[j][0] < k)
				x = j, fl = 0, k = dis[j][0];
			else if (!vis[j][1] && dis[j][1] < k)
				x = j, fl = 1, k = dis[j][1];
		}
		if (k == 0x3f3f3f3f)
			break;
		vis[x][fl] = 1;
		for (j = 0; j < to[x].size(); j++)
		{
			y = to[x][j];
			if (dis[y][0]>k + val[x][j])
			{
				dis[y][1] = dis[y][0], cnt[y][1] = cnt[y][0];
				dis[y][0] = k + val[x][j], cnt[y][0] = cnt[x][fl];
			}
			else if (dis[y][0] == k + val[x][j])
				cnt[y][0] += cnt[x][fl];
			else if (dis[y][1] > k + val[x][j])
				dis[y][1] = k + val[x][j], cnt[y][1] = cnt[x][fl];
			else if (dis[y][1] == k + val[x][j])
				cnt[y][1] += cnt[x][fl];
		}
	}
	if (dis[t][1] == dis[t][0] + 1)
		cnt[t][0] += cnt[t][1];
	printf("%d\n", cnt[t][0]);
}
int main()
{
	int c, T, n, m, i, j, k, x, y, v;
	scanf("%d", &T);
	for (c = 1; c <= T; c++)
	{
		scanf("%d%d", &n, &m);
		init(n);
		for (i = 1; i <= m; i++)
		{
			scanf("%d%d%d", &x, &y, &v);
			to[x].push_back(y);
			val[x].push_back(v);
		}
		Dij(n);
	}
	return 0;
}


版权声明:

相关文章推荐

POJ 3463 Sightseeing Dijkstra最短路&最短路-1的路径数(计数)

题目大意:求给定的DAG中最短路&z

【POJ】3463 Sightseeing 最短路+比最短路大一的路(最短路 or 最短路+DP)

Sightseeing Time Limit: 2000MS   Memory Limit: 65536K Total Submissions: 6951   Ac...

POJ 3463 Sightseeing 最短路+次短路

题意:给定一个有向图,问从起点到终点,最短路+比最短路距离长1的路的个数。 思路:最短路+次短路。 #include #include #include #include #inclu...

POJ 3463 Sightseeing (第k短路)

~~题目链接~~~ 题目大意:给出一个旅游路线,现在要求求它的最短路和比最短路长1的路共有多少条。 思路:看代码吧 #include #include #define...

poj 3463 Sightseeing 将spfa进行到底!!!

谁说这题只能用dijkstra!!!劳资就用spfa + 搜索dp把它秒了!! 不过真tm的难写!!细节之多是难以想象的!! wa了无数次之后我甚至开始怀疑我的方法的正确性,主要是因为图是多重图啊!...

poj3463 Sightseeing

/* * poj3463 AC * 求最短路径以及次短路径的总数。 * Dijkstra+一点变化。 * 与最短路径的Dijkstra的相比,记录的东西要增加。 * 算法: * 首先,要...

【Dijkstra+邻接表求次短路】POJ Sightseeing 3463

Language: Default Sightseeing Time Limit: 2000MS   Memory Limit: 65536K Total Submissions: 77...
  • ydd97
  • ydd97
  • 2015-08-24 00:37
  • 2067

poj 3463 Sightseeing

题意:旅行团每天固定的从S地出发到达T地,为了省油要求尽量走最短路径或比最短路径长1单位距离的路径,求满足条件的路径条数 这是一次对dijstra的深刻理解 ,好吧......不会做,参考大神思路 ...

poj3463——Sightseeing

最短路拓展。详见: http://blog.csdn.net/leeeyupeng/archive/2010/08/06/5790928.aspx#include #include #inclu...

POJ-3463: Sightseeing 【最短路次短路及条数】

Sightseeing Time Limit: 2000MS   Memory Limit: 65536K Total Submissions: 9247   Ac...
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:深度学习:神经网络中的前向传播和反向传播算法推导
举报原因:
原因补充:

(最多只允许输入30个字)