gym103117L. Spicy Restaurant
题意:
有n个点,m个边,每个点都有一个能量值,现在有q个人,每个人有自己的能量值,现在每个人都要去离自己最近且能量值小于等于自身的点。
1<=n,m<=1e5
1<=q<=5e5
1<=wi<=1001<=w_{i}<=1001<=wi<=100
题解:
按照题目意思,对于q个人我们都要跑一次最短路,直接爆掉
我们注意到,wi很小范围是100以内,那我们可以这样,对于辣味x,如果有三个点辣味等于x,我们可以以他们为起点,然后跑bfs,去更新与其他点的距离,这样跑完相当于知道了其他点到辣味x的城市的最近距离。d[i][j]:表示点j到最近的辣味为i的点之间的距离,然后将dis[i][j]=min(dis[i-1][j],dis[i][j])顺着更新(因为可以到达辣度小于等于i的点)
辣味x只需要从1循环到100,每次跑多源bfs。最后询问时直接查询即可
总复杂度是O(100(n+m)+100n+q)
代码:
我一开始输出用的cout,直接被卡了
#include <bits/stdc++.h>
#include <unordered_map>
#define debug(a, b) printf("%s = %d\n", a, b);
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
typedef pair<int, int> PII;
clock_t startTime, endTime;
//Fe~Jozky
const ll INF_ll= 1e18;
const int INF_int= 0x3f3f3f3f;
void read(){};
template <typename _Tp, typename... _Tps> void read(_Tp& x, _Tps&... Ar)
{x= 0;char c= getchar();bool flag= 0;while (c < '0' || c > '9')flag|= (c == '-'), c= getchar();while (c >= '0' && c <= '9')x= (x << 3) + (x << 1) + (c ^ 48), c= getchar();if (flag)x= -x;read(Ar...);
}
template <typename T> inline void write(T x)
{if (x < 0) {x= ~(x - 1);putchar('-');}if (x > 9)write(x / 10);putchar(x % 10 + '0');
}
void rd_test()
{
#ifdef ONLINE_JUDGE
#elsestartTime = clock ();freopen("data.in", "r", stdin);
#endif
}
void Time_test()
{
#ifdef ONLINE_JUDGE
#elseendTime= clock();printf("\nRun Time:%lfs\n", (double)(endTime - startTime) / CLOCKS_PER_SEC);
#endif
}
const int maxn=200010;
int w[maxn];
vector<int>vec[maxn];
int dis[102][maxn];
int vis[maxn];
int n,m,q;
void bfs(int x){queue<int>q;for(int i=1;i<=n;i++){vis[i]=0;if(w[i]==x){q.push(i);dis[x][i]=0;}}while(!q.empty()){int u=q.front();q.pop();
// vis[u]=1;for(auto v:vec[u]){if(vis[v])continue;vis[v]=1;dis[x][v]=min(dis[x][u]+1,dis[x][v]);q.push(v);}}
}
int main()
{rd_test();read(n,m,q);for(int i=1;i<=n;i++){for(int j=0;j<=100;j++){dis[j][i]=INF_int;}}for(int i=1;i<=n;i++)read(w[i]); for(int i=1;i<=m;i++){int u,v;read(u,v);vec[u].push_back(v);vec[v].push_back(u);}for(int i=1;i<=100;i++)bfs(i);for(int i=1;i<=n;i++){for(int j=1;j<=100;j++){dis[j][i]=min(dis[j][i],dis[j-1][i]);} }for(int i=1;i<=q;i++){int p,a;//位置 辣度 read(p,a);printf("%d\n",(dis[a][p]==INF_int?-1:dis[a][p]));}return 0;//Time_test();
}