这里有 n 座城市,编号 1 ~ n。n 座城市之间由 m 条双向道路相连,保证任意两所城市可相互到达。
学校位于第 k 座城市。临近寒假,来自各个城市的同学们都在准备回家过年,但因为特殊原因,现在所有城市都被封锁起来了(第 0 天)。
归乡心切的 Cofe_Milk 得到最新消息,从明天(第 1 天)开始,每天都将有一座城市解封。对于需要回到这座城市的同学,若想到达这座城市,则从学校出发,到达这座城市的路径上的所有城市都应是解封状态(当然,路径也包括学校所在城市与目的地城市)。我们称来自这所城市的同学的回家日便是他们可以回家的最小日期。
特别的:家在第 k 所城市的同学也需要第 k 所城市解封才能回去。
请分别求出来自 1 ~ n 城市的同学的回家日。
//想了很久,想到了a[i]表示第i点的a[i]天解封,想到了邻接表
//没想到//跟i相连的a[j]或者dist[i]大即可
#include<bits/stdc++.h>
using namespace std;
const int N=4e5+10;
int n,m,k;
int a[N];
int h[N],e[N],ne[N],idx;
int dist[N];
void add(int x,int y){
e[idx]=y;
ne[idx]=h[x];
h[x]=idx++;
}
int spfa(){
//跟i相连的a[j]或者dist[i]大即可
memset(dist,0x3f,sizeof dist);
queue<int> q;
dist[k]=a[k]; q.push(k);
while(q.size()){
int t=q.front(); q.pop();
for(int i=h[t];i!=-1;i=ne[i]){
int j=e[i], maxv = max(dist[t], a[j]);
if(maxv < dist[j]) q.push(j), dist[j] = maxv;
}
}
for(int i=1;i<n;i++) cout<<dist[i]<<" ";cout<<dist[n];
return 0;
}
int main()
{
ios::sync_with_stdio(0);
cin.tie(0),cout.tie(0);
memset(h,-1,sizeof h);
cin>>n>>m>>k;
for(int i=1;i<=n;i++) {
int f; cin>>f; a[f]=i;//第i天第f个城市解封
};
while(m--){
int x,y; cin>>x>>y;
add(x,y); add(y,x);
}
spfa();
return 0;
}
考试将至,cofe 好好复习了一段时间后,准备写下试卷验证下自己的学习成果。由于 cofe 懒散的天性使他只想刷一套卷,便打算从 N 套卷子(编号 1−N)中选取题目来组一套。
一套题中有若干 难度-题号 的题目,题号各不相同,难度有 T1 到 T10 十个级别 。cofe 对每个难度的题都有一个期望数,即期望写这个难度题的数量。然而卷子是有限的,cofe 所期望的某个难度的题不一定能达到。于是组题时会优先使每个难度的题尽量先达到期望数。
而那些没有达到期望数的,只能选取其他难度的题从而保证实际总题数与期望总题数相等,这里cofe 给出一种选题策略。
设没达到期望数的难度为 Ti,Ti 从小到大
选取难度 >Ti 且难度最接近 Ti 的尚未选取的题目,若没得取,则取难度 <Ti 且难度最接近 Ti 的尚未选取的题目
执行上一步的次数为取 Ti 的期望数与实际数的差值,取完后 Ti 增大
选取的具体题目则受输入的先后顺序影响,先输入的题目先取。
题目保证卷子总题数大于等于期望总题数。
//纯粹用vector的v[x].push_back({j,y})、v[j].front()、 v[j].erase(v[j].begin())
#include<bits/stdc++.h>
using namespace std;
typedef pair<int,int> PII;
int n,idx;
int a[15];
struct node{
int difficulty;
int juan;
int timu;
}oo[10010];
bool cmp(node s1,node s2){
if(s1.difficulty!=s2.difficulty) return s1.difficulty<s2.difficulty;
if(s1.juan!=s2.juan) return s1.juan<s2.juan;
return s1.timu<s2.timu;
}
int main()
{
cin>>n;
vector<PII> v[15];
for(int i=1;i<=10;i++) cin>>a[i];//输入待取题目难度套数
for(int j=1;j<=n;j++){
int k;cin>>k;
for(int i=0;i<k;i++){
char c,s;
int x,y;
cin>>c>>x>>s>>y;
v[x].push_back({j,y});//x有{题号y,第j套}
}
}
for(int i=1;i<=10;i++){
if(a[i]!=0){
for(int j=i;j<=10;j++){
while(v[j].size()){
PII k=v[j].front();
v[j].erase(v[j].begin());
oo[idx]={j,k.first,k.second};
idx++;
a[i]--;
if(a[i]==0) break;
}
if(a[i]==0) break;
}
if(a[i]!=0){
for(int j=i-1;j>=1;j--){
while(v[j].size()){
PII k=v[j].front();
v[j].erase(v[j].begin());
oo[idx]={j,k.first,k.second};
idx++;
a[i]--;
if(a[i]==0) break;
}
if(a[i]==0) break;
}
}
}
}
sort(oo,oo+idx,cmp);
int i;
for(i=0;i<idx-1;i++){
cout<<oo[i].juan<<"-"<<oo[i].timu<<" ";
}
cout<<oo[i].juan<<"-"<<oo[i].timu;
return 0;
}