关于典型的点权转边权的题目,求大佬帮忙调一下
  • 板块灌水区
  • 楼主Zhang_Wenjie
  • 当前回复1
  • 已保存回复1
  • 发布时间2024/5/29 21:31
  • 上次更新2024/5/30 12:14:50
查看原帖
关于典型的点权转边权的题目,求大佬帮忙调一下
481621
Zhang_Wenjie楼主2024/5/29 21:31

逃晚自习搞的,时间宝贵,没办法就发这了,感谢

P3393 逃离僵尸岛

#include <bits/stdc++.h>
#define re register int 
using namespace std;
typedef long long LL;
typedef pair<LL, int> PII;
const int N = 1e5 + 10, M = 4e5 + 10;
const LL inf = LLONG_MAX;

struct edge
{
	int to, w, next;
}e[M];
int top, h[N];
int n, m, k, gap, p, q, c[N], a[N], b[N];
LL dist[N];
bool vis[N], flag[N], pass[N];

inline void add(int x, int y, int w)
{
	e[++ top] = (edge){y, w, h[x]};
	h[x] = top;
}

inline void bfs(int s)
{
	int cnt = 0;
	bool tmp[N]; memset(tmp, false, sizeof(tmp));
	queue<int> q;
	
	q.push(s);
	flag[s] = tmp[s] = true;
	
	while (!q.empty())
	{
		int x = q.front(); q.pop();
		
		if (cnt == gap) break;
		
		bool tag = false;
		for (re i = h[x]; i; i = e[i].next)
		{
			int y = e[i].to;
			
			if (!tag) tag = true, cnt ++;
 			if (!tmp[y])
			{
				tmp[y] = true;
				q.push(y);
			} 
		}
	}
	
	for (re i = 1; i <= n; i ++)
		if (tmp[i]) pass[i] = true;
}

inline void dijkstra()
{
	priority_queue<PII, vector<PII>, greater<PII> > q;
	
	memset(vis, false, sizeof(vis));
	for (re i = 1; i <= n; i ++) dist[i] = inf;
	
	dist[1] = 0;
	q.push(make_pair(0, 1));
	
	while (!q.empty())
	{
		int x = q.top().second; q.pop();
		if (vis[x]) continue;
		vis[x] = true;
		
		for (re i = h[x]; i; i = e[i].next)
		{
			int y = e[i].to, w = e[i].w;
			
			if (flag[y]) continue;
			if (dist[y] > dist[x] + w)
			{
				dist[y] = dist[x] + w;
				q.push(make_pair(dist[y], y));
			}
		} 
	}
}

int main()
{
	ios::sync_with_stdio(false);
	cin.tie(0); cout.tie(0);
	
	cin >> n >> m >> k >> gap >> p >> q;
	for (re i = 1; i <= k; i ++) 
	{
		cin >> c[i];
		flag[c[i]] = true;
	}
	for (re i = 1; i <= m; i ++)
	{
		cin >> a[i] >> b[i];
		add(a[i], b[i], 0); add(b[i], a[i], 0);
	}
	for (re i = 1; i <= k; i ++)
		bfs(c[i]);

	memset(e, 0, sizeof(e));
	memset(h, 0, sizeof(h));
	top = 0;
	
	for (re i = 1; i <= m; i ++)
	{	
		if (pass[b[i]]) add(a[i], b[i], q);
		else add(a[i], b[i], (b[i] == n ? 0 : p));
		
		if (pass[a[i]]) add(b[i], a[i], q);
		else add(b[i], a[i], (a[i] == n ? 0 : p));
	}
	dijkstra();
	
	cout << dist[n] << '\n';
	
	return 0;
}
2024/5/29 21:31
加载中...