您的位置:首页 > 其它

[测试题]香港记者

2017-08-21 16:46 246 查看

Description

众所周知,香港记者跑得比谁都快,这其中其实是有秘诀的。
首先他们会跑最短路,但是最短路会有很多条,而且其他记者也知道要跑最短路,香港记者还统计出了每座城市带黑框眼镜的人数,如果一个记者跑路的时候城市带黑框眼镜人数的序列字典序比另一个记者大,那么这个记者就会被不可描述的力量续走时间,导致他跑得没字典序小的记者快。
长者日续万秒日理万机,想请你告诉他香港记者经过的总路程和城市带黑框眼镜人数的序列,方便他找到香港记者,传授他们一些人生经验。
方便起见,设起点为 1 终点为 n。
由于续命的多样性不可描述的力量,各个城市带黑框眼镜的人数各不相同。

Input

输入文件名为 journalist.in。
第一行,两个整数 n; m 表示有 n 个城市,城市之间有 m 条有向边。
第二行, n 个数,表示每个城市带黑框眼镜的人数 bi:
接下来 m 行,每行 3 个非负整数 ui; vi; wi 表示一条有向边的起点,终点,路程。

Output

输出文件名为 journalist.out。
第一行,一个非负整数表示香港记者经过的总路程。
第二行,若干个非负整数表示香港记者经过的城市带黑框眼镜人数的序列。

Sample Input

8 9
1 2 3 4 5 6 7 8
1 2 2
2 3 3
3 8 3
1 4 3
4 5 2
5 8 1
1 6 1
6 7 2
7 8 3

Sample Output

6
1 4 5 8

Hint

对于前 30% 的数据, 2 ≤ n ≤ 2 × 103, 1 ≤ m ≤ 4 × 103。
对于前 60% 的数据,保证数据随机。
对于另外 30% 的数据,保证所有起点到终点的简单路径(没有环的路径)长度相同。
对于 100% 的数据, 2 ≤ n ≤ 2 × 105, 1 ≤ m ≤ 4 × 105, 1 ≤ w ≤ 1 × 109,存在至少一条从
起点到终点的最短路。

题解

解法一:

我们可以先求出最短路。

然后搜索求出路径。

对于$u->v$,如果

$$dist[v]==dist[u]+w(u,v)$$

就继续拓展。

我们可以加边的时候先将后继节点按点权排序,这样贪心保证搜出的第一条策略就是满足条件的。

#include<set>
#include<map>
#include<cmath>
#include<ctime>
#include<queue>
#include<stack>
#include<vector>
#include<cstdio>
#include<string>
#include<cstdlib>
#include<cstring>
#include<iostream>
#include<algorithm>
#define LL long long
#define RE register
#define IL inline
using namespace std;
const int N=2e6;
const int INF=~0u>>1;

IL int Read()
{
int sum=0;
char c=getchar();
while (c<'0'||c>'9') c=getchar();
while (c>='0'&&c<='9') sum=sum*10+c-'0',c=getchar();
return sum;
}
IL void put(int d)
{
if (!d) return;
put(d/10);
putchar(d%10+'0');
}

IL int Min(const int &a,const int &b) {return a<b ? a:b;}
IL int Max(const int &a,const int &b) {return a>b ? a:b;}

int t,n,k,f,maxn;
int a[N+5];
int s[N+5];

int main()
{
t=Read();
while (t--)
{
n=Read();k=Read();f=Read();
maxn=0;
memset(s,0,sizeof(s));
for (RE int i=1;i<=n;i++) a[i]=Read(),maxn=Max(maxn,a[i]),s[a[i]]++;
for (RE int i=1;i<=maxn;i++) s[i]+=s[i-1];
for(RE int d=1;d<=maxn;d++)
{
int cnt=s[d-1];
for(RE int j=d;cnt<=f&&j+k+1<=maxn;j+=d)
if (j+k<Min(maxn,j+d-1)) cnt+=s[Min(maxn,j+d-1)]-s[j+k];
if (cnt<=f) put(d),putchar(' ');
}
putchar('\n');
}
return 0;
}


解法二
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: