hdu 5385 The path(最短路+构造)

题目链接:hdu 5385 The path

维护一个l,r,l从2开始递增,r从N开始递减,每个距离值l,r至多走一步,并且每次将可以到达的点标记,注意最后最大值只能有一个。

#include <cstdio>
#include <cstring>
#include <vector>
#include <queue>
#include <algorithm>

using namespace std;
typedef pair<int,int> pii;
const int maxn = 1e5 + 5;

int N, M, D[maxn], R[maxn];
int X[maxn], Y[maxn], W[maxn];
vector<pii> G[maxn];

void init () {
	scanf("%d%d", &N, &M);
	memset(R, 0, sizeof(R));
	for (int i = 1; i <= N; i++) {
		D[i] = -1;
		G[i].clear();
	}

	for (int i = 1; i <= M; i++) {
		W[i] = -1;
		scanf("%d%d", &X[i], &Y[i]);
		G[X[i]].push_back(make_pair(Y[i], i));
		//G[Y[i]].push_back(make_pair(X[i], i));
	}
}

void solve () {
	D[1] = 0;
	queue<int> Q;
	Q.push(1);

	int l = 2, r = N;
	for (int d = 1; d <= N; d++) {
		if (r < l)
			break;
		while (!Q.empty()) {
			int u = Q.front();
			Q.pop();

			for (int i = 0; i < G[u].size(); i++) {
				int v = G[u][i].first;
				if (R[v])
					continue;
				R[v] = G[u][i].second;
			}
		}

		if (R[l]) {
			D[l] = d;
			int u = X[R[l]] + Y[R[l]] - l;
			W[R[l]] = D[l] - D[u];
			Q.push(l++);
		}
		if (r > l && R[r]) {
			D[r] = d;
			int u = X[R[r]] + Y[R[r]] - r;
			W[R[r]] = D[r] - D[u];
			Q.push(r--);
		}
	}

	/*
	for (int i = 1; i <= N; i++)
		printf("%d ", D[i]);
	printf("\n");
	*/
}

int main () {
	int cas;
	scanf("%d", &cas);
	while (cas--) {
		init ();
		solve ();
		for (int i = 1; i <= M; i++)
			printf("%d\n", W[i] == -1 ? N : W[i]);
	}
	return 0;
}

版权声明:本文为博主原创文章,未经博主允许不得转载。

时间: 2024-10-07 03:50:40

hdu 5385 The path(最短路+构造)的相关文章

hdu 5385 The path

HDU 5385   构造题 使用贪心法构造,因为保证有解,点2或n至少有一个直接与点1相连 上述结论可以用反证法证明. 假若2和n不直接与1相连,那么必存在点x直接与1相连,间接与2,n相连.这种情况下无论如何设置边权,都有d[x]<d[2]&&d[x]<d[n],与已知矛盾 那么可以按照每次添加两头的点与1相连,记添加时间为1到该点的最短路,边添加边计算边权 然后不在最短路树上的边权都设为n即可,这样不会使最短路树发生变化 #include<cstdio> #i

HDU 4889 Scary Path Finding Algorithm

题意: 构造一幅图  使题中给出的程序按该图执行  最终变量doge大于输入的C跳出 思路: 出题人思维简直神了!  实在是膜拜!  借题解的图: 按照图中所画  可以继续向右延伸 为何这样可以??  为何边权要这么取?? 先回答第二个问题: 取负数是为了可以不断的去更新  例如如果走了上面的-4那条边  那么它右边的所有点就又可以再更新一次  这样使更新达到了指数级别 (其实可以把所有的值加上一个值K  不过这个K一定要取好!) 除了负数外我们发现数字都是2的几次幂  如果我们按2进制来考虑的

HDU 3832 Earth Hour (最短路)

Earth Hour Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 125536/65536 K (Java/Others)Total Submission(s): 1518    Accepted Submission(s): 607 Problem Description Earth Hour is an annual international event created by the WWF (World Wide Fun

HDU 1491 社交网络(最短路计数)

题目链接:http://61.187.179.132/JudgeOnline/problem.php?id=1491 题意:给出一个联通的无向图,边有权值.定义I(v)如下,计算每个点的I值. 思路:(1)最简单的就是那个floyd了...g[i][j]记录最短路长度,f[i][j]记录个数,不多说了: (2)下面说说我自己想出来的算法..枚举s和t,计算每个点到s和t的最短路..然后建立最短路树..之后求s到t的最短路个数..然后枚举删掉某个点再求最短路个数,则差值即为通过删掉点的最短路数目.

HDU1839_Delay Constrained Maximum Capacity Path(最短路+二分)

解题报告 http://blog.csdn.net/juncoder/article/details/38349019 题目传送门 题意: 有N个点,点1为珍贵矿物的采矿区, 点N为加工厂,有M条双向连通的边连接这些点.走每条边的运输容量为C,运送时间为D. 他们要选择一条从1到N的路径运输, 这条路径的运输总时间要在T之内,在这个前提之下,要让这条路径的运输容量尽可能地大. 一条路径的运输容量取决与这条路径中的运输容量最小的那条边. 思路: 二分容量建图,spfa判时间是否符合条件 #incl

hdu 5168 Legal path

题目链接: http://acm.hdu.edu.cn/showproblem.php?pid=5168 题意: 一个有向图,给定起点终点,每条边上有权值. 一条合法的路径定义为相邻边的权值之差不小于K的路径,即路径上每条边的权值至少要比上一条边的权值大K,如果上一条边存在.合法路径的长度定义为路径上的边权值总和. 求从起点到终点的合法路径的最短长度. 限制: 有多组数据,第一行为数据组数T(T≤10). 对于每组数据,第一行为三个整数n,m,K,n,m分别表示这组数据的有向图的点数,边数,起点

HDU 4856 Tunnels (最短路+状压DP)

题意:给你N*N的网格,'.'表示可以走,'#'表示不能走,m条管道,每条管道有起点和终点坐标, Bob每次可以走到相邻的网格花费1s,问Bob走完m条管道要花多少时间:Bob在管道内不计算时间 即计算Bob从管道 i 的出口走到管道 j 的入口的时间Dis(e[i],s[j])的最小和,起点可以任意: 思路:看了题解说是状态压缩DP然后深入理解了下. 首先算出d[e[i]][s[j]]的最短距离,不能到达为-1: dp[i][j] : 表示以 j 为起点状态为 i 的最小值.其中 i 是用十进

HDU 2833 WuKong(floyd最短路)

题目地址:HDU 2833 这题想到了最后是通过dis[s][t]==dis[s][i]+dis[i][j]+dis[j][t]的思路来判定是否属于最短路的一条..但是没想到可以用floyd来找最短路中的点数...最短路还是太渣了..好多性质都不会利用.. 这题的思路就是通过floyd对每两个点之间的最短路条数进行计数,然后通过上面的公式(对两条路线均要判定,都符合才说明都可以走),再找最短路中的最大点数. 代码如下: #include <iostream> #include <stdi

HDU 1976 prime path

题意:给你2个数n m,从n变成m最少需要改变多少次. 其中: 1.n  m  都是4位数 2.每次只能改变n的一个位数(个位.十位.百位.千位),且每次改变后后的新数为素数 思路:搜索的变形题,这次我们要搜得方向是改变位数中的一位,然后往下搜,直到求出我们需要的那个解 #include<cstdio> #include<cstring> #include<algorithm> #include<queue> #include<cmath> us