传送门
B. Fire-Fighting Hero
解:给消防队加一个源点0,从他开始跑一次dijkstra,再取最大值。消防英雄的话跑一次,两次dijkstra即可。
#include<bits/stdc++.h>
#define il inline
#define pb push_back
#define ms(_data,v) memset(_data,v,sizeof(_data))
#define SZ(a) int((a).size())
using namespace std;
typedef long long ll;
const ll inf=1e18+5;
const int maxn=1e3+5;
struct node {
ll p,dis;
bool operator <(const node& x)const {
return dis>x.dis;
}
};
struct edge {
ll to,w;
};
vector<edge> e[maxn];
bool vis[maxn];
ll dist[maxn];
int n,m,s,k,c;
il void Dijkstra(int start) {
for(int i=0; i<=n; ++i) dist[i]=inf,vis[i]=false;
dist[start]=0;
priority_queue<node> q;
q.push(node {start,0});
while(!q.empty()) {
node tmp=q.top();
q.pop();
int np=tmp.p;
if(vis[np]) continue;
else {
vis[np]=1;
for(int i=0; i<e[np].size(); ++i) {
edge ne=e[np][i];
ll nto=ne.to,nw=ne.w;
if(dist[nto]>dist[np]+nw) {
dist[nto]=dist[np]+nw;
q.push(node {nto,dist[nto]});
}
}
}
}
}
//il int Add(ll &x,ll y) {return x=x+y>=mod?x+y-mod:x+y;}
//il int Mul(ll &x,ll y) {return x=x*y>=mod?x*y%mod:x*y;}
int T,p[maxn];
int main() {
scanf("%d",&T);
unordered_set<int> fr;
while(T--) {
fr.clear();
scanf("%d%d%d%d%d",&n,&m,&s,&k,&c);
for(int i=0; i<=n; ++i) e[i].clear();
for(int i=0; i<k; i++) {
scanf("%d",p+i);
e[0].push_back({p[i],0});
}
int u,v,l;
for(int i=0; i<m; i++) {
scanf("%d%d%d",&u,&v,&l);
fr.insert(v),fr.insert(u);
e[u].push_back({v,l});
e[v].push_back({u,l});
}
ll H=0,P=0;
Dijkstra(s);
for(auto it = fr.begin(); it!=fr.end(); ++it) {
H=max(dist[*it],H);
}
Dijkstra(0);
for(auto it = fr.begin(); it!=fr.end(); ++it) {
P=max(dist[*it],P);
}
if(H>1LL*P*c) printf("%lld\n",P);
else printf("%lld\n",H);
}
return 0;
}
一开始那个解法假了,数据太弱了。
E. Magic Master
解:就是约瑟夫环,根据题意,那就是第几个拿出来的那就是第几,直接用静态链表模拟即可(4e9)。
开数组比开结构体快了将近一倍,被卡成憨憨。
#include<bits/stdc++.h>
#define il inline
#define pb push_back
#define ms(_data,v) memset(_data,v,sizeof(_data))
#define SZ(a) int((a).size())
using namespace std;
typedef long long ll;
const ll inf=0x3f3f3f3f;
const int N=4e7+5;
//il int Add(ll &x,ll y) {return x=x+y>=mod?x+y-mod:x+y;}
//il int Mul(ll &x,ll y) {return x=x*y>=mod?x*y%mod:x*y;}
int T,ans[N];
int pre[N],nxt[N];
int main() {
scanf("%d",&T);
int n,m,q,x;
while(T--) {
scanf("%d%d%d",&n,&m,&q);
for(int i=1; i<=n; ++i) {
if(i==1) pre[i]=n;
else pre[i]=i-1;
if(i==n) nxt[i]=1;
else nxt[i]=i+1;
}
if(n==2) {
ans[1]=1,ans[2]=2;
} else {
ans[1]=1;
pre[2]=pre[1];
nxt[pre[1]]=nxt[1];
n--;
int nt,j=2,cnt=1;
int npre,nnxt;
while(n) {
nt=m;
while(nt--) {
j=nxt[j];
}
ans[j]=++cnt;
if(n==2) {
ans[nxt[j]]=++cnt;
break;
}
npre=pre[j],nnxt=nxt[j];
j=nxt[j];
nxt[npre]=nnxt,pre[nnxt]=npre;
n--;
}
}
while(q--) {
scanf("%d",&x);
printf("%d\n",ans[x]);
}
}
return 0;
}