Campus
题目链接
题意:
在樱花季节,WHU(一个有n个节点和m条边的无向图)吸引了大量游客,给管理带来了困扰。每个节点初始时有ai名游客,其中有k个节点是校门,这些校门有自己的开放时间区间[li, ri]。假设存在一个“魔法按钮”,按下后所有游客会以光速从最近的开放校门离开校园。要求计算从第1时刻到第T时刻,每时刻离开校园的所有游客所走过的距离总和。若某个时刻有任何游客无法离开,则该时刻的距离总和视为-1。
思路:
很显然的一个思路,处理出每一个门到各个节点的最短路,在一个时刻中,每个节点的人都从开的那些门中选一个路径最短的门离去。有T个时刻,最暴力的方法肯定不行,我们可以预处理每一个时刻对应的门状态。最后注意一下大门全部关闭的时刻输出-1即可。
点击查看代码
#include <bits/stdc++.h>
using namespace std;
#define endl '\n'
#define int long long
#define ll long long
const int N = 1e5+5;
int a[N];
int p[20],l[20],r[20];
struct edge{
int next,vi,wi;
edge(){}
edge(int _next,int _vi,int _wi){
next=_next,vi=_vi,wi=_wi;
}
}e[N<<1];
int head[N],index;
void insert(int a,int b,int c){
e[index]=edge(head[a],b,c);
head[a]=index++;
}
bool vis[N];
map<int,vector<int>>mp; //mp映射不同状态的最短路
void dj(int u){ //以u为起点跑一个最短路
memset(vis,0,sizeof(vis));
vector<int>v(N,0x7fffffffffffffff);
mp[u]=v;
mp[u][u]=0;
set<pair<int,int>>s;
s.insert({0,u});
while(!s.empty()){
int dingdian=(*s.begin()).second;
s.erase(s.begin());
if(vis[dingdian]) continue;
vis[dingdian]=1;
for(int j=head[dingdian];~j;j=e[j].next){
int v=e[j].vi;
int w=e[j].wi;
if(!vis[v]&&mp[u][v]>mp[u][dingdian]+w){
mp[u][v]=mp[u][dingdian]+w;
s.insert({mp[u][v],v});
}
}
}
}
map<vector<int>,vector<int>>t; //以门的状态映射时刻
int ans[N];
void solve(){
memset(head,-1,sizeof(head));
index=0;
int n,m,k,T;
cin>>n>>m>>k>>T;
for(int i=1;i<=n;++i){
cin>>a[i];
}
for(int i=1;i<=k;++i){
cin>>p[i]>>l[i]>>r[i];
}
for(int i=1;i<=m;++i){
int u,v,w;
cin>>u>>v>>w;
insert(u,v,w);
insert(v,u,w);
}
for(int i=1;i<=k;++i){
dj(p[i]);
}
for(int i=1;i<=T;++i){
vector<int>v;
for(int j=1;j<=k;++j){
if(i>=l[j]&&i<=r[j]){
v.push_back(p[j]);
}
}
t[v].push_back(i);
}
for(auto i=t.begin();i!=t.end();++i){
vector<int>v=i->first;
int cnt=0;
int len=v.size();
if(len==0){
cnt=-1;
}else{
for(int j=1;j<=n;++j){
int zuixiao=0x7fffffffffffffff;
for(int h=0;h<len;++h){
zuixiao=min(zuixiao,mp[v[h]][j]); //找最近的门
}
cnt+=zuixiao*a[j];
}
}
for(int j=0;j<i->second.size();++j){
ans[i->second[j]]=cnt;
}
}
for(int i=1;i<=T;++i){
cout<<ans[i]<<endl;
}
}
signed main(){
ios::sync_with_stdio(0),cin.tie(0),cout.tie(0);
int _=1;
// cin>>_;
while(_--)
solve();
return 0;
}

浙公网安备 33010602011771号