1月6日考试总结

发布时间 2024-01-07 11:15:34作者: CQWYB

考炸了,赛时只做出了一道题。

A 过关斩将

做法

这道题就是一个很显然的二维最短路,设 \(dis[i][j]\) 表示到达点 \(i\) 且当前的状态为 \(j\) 的最少代价。其中 \(j=0\) 时表示状态为 \(L\)\(j=1\) 时表示状态为 \(R\)

很显然可以用 \(dijkstra\) 来求解,转移方程为 \(dis[v][v.type] = dis[u][u.type] + w(u.type==v.type)\)

也可以为 \(dis[v][u.type] = dis[u][u.type] + w(v.type==M)\)

还有种情况 \(dis[v][v.type] = dis[u][u.type] + w + x(v.type\ne u.type ~~ and ~~ v.type \ne 2)\)

答案为 \(min(dis[t][0],dis[t][1])\)

\(Code\)

#include<bits/stdc++.h>
#define int long long
using namespace std;
const int N=2e5+50;
int T,cnt;
int n,m,s,t,x;
int head[N];
struct edge{
	int to,nxt,w;
}e[N*4];
void add(int u,int v,int f)
{
	e[++cnt].to=v;
	e[cnt].nxt=head[u];
	head[u]=cnt;
	e[cnt].w=f;
	return;
}
string ss;
bool vis[N][4];
int dis[N][4];
struct node{
	int val,pos,type;
	bool operator >(const node &x)const
	{
		return val>x.val;
	}
};
void dij(int S)
{
	for(int i=1;i<=n;i++){
		for(int j=0;j<=2;j++)
		{
			dis[i][j]=1e18;
			vis[i][j]=0;
		}
	}
	if(ss[S]=='L')dis[S][0]=0;
	else if(ss[S]=='R')dis[S][1]=0;
	else if(ss[S]=='M')dis[S][0]=0,dis[S][1]=0;
	priority_queue<node,vector<node>,greater<node> >q;
	q.push(node{dis[S][0],S,0});q.push(node{dis[S][1],S,1});
	while(!q.empty())
	{
		node t=q.top();q.pop();
		if(vis[t.pos][t.type])continue;
		vis[t.pos][t.type]=1;
		for(int i=head[t.pos];i;i=e[i].nxt)
		{
			int v=e[i].to;
			int op=-1;
			if(ss[v]=='L')op=0;
			else if(ss[v]=='R')op=1;
			else if(ss[v]=='M')op=2;
			if(op==t.type&&dis[v][op]>dis[t.pos][t.type]+e[i].w)
			{
				dis[v][op]=dis[t.pos][t.type]+e[i].w;
				q.push(node{dis[v][op],v,op});
			}
			else if(op==2&&dis[v][t.type]>dis[t.pos][t.type]+e[i].w)
			{
				dis[v][t.type]=dis[t.pos][t.type]+e[i].w;
				q.push(node{dis[v][t.type],v,t.type});
			}
			else if(dis[v][op]>dis[t.pos][t.type]+x+e[i].w)
			{
				dis[v][op]=dis[t.pos][t.type]+e[i].w+x;
				q.push(node{dis[v][op],v,op});
			}
		}
	}
	return;
}
signed main()
{
	scanf("%lld",&T);
	while(T--)
	{
		cnt=0;
		scanf("%lld %lld %lld %lld %lld",&n,&m,&s,&t,&x);
		for(int i=1;i<=n+50;i++)head[i]=0;
		cin>>ss;
		ss=" "+ss;
		for(int i=1,u,v,w;i<=m;i++)
		{
			scanf("%lld %lld %lld",&u,&v,&w);
			add(u,v,w);add(v,u,w);
		}
		dij(s);
		printf("%lld\n",min(dis[t][0],dis[t][1]));
	}
	return 0;
}