题意:
有n个点,m条边的无向带权图,每一个点都有一个字母类型,每个点的类型有三种L,R,M。
L能转R,R转L,且需要花费x。
从L结点到R结点需要多花费x(要转换),L或R结点到M结点,M结点可以为R结点也可以为L结点,所以 在进过M结点时你要选择是变R还是L。
所以要进行拆点。
注意: 当起点为M时,你需要增加一个0结点,连接到起点拆分之后的两个结点。当终点为M时,同理增加一个2*n+1结点连接终点拆分之后的两个结点。
拆分:
若u和v结点状态同时为L或R: 在u和v之间连一条权值为w的无向边。
若u为L,v为R: 在u和v之间连一条权值为w+x的无向边。
若v为L,u为R: 在u和v之间连一条权值为w+x的无向边。
若u为L,u为M: 在u和v之间连一条权值为w的无向边。同时在u和v+n之间连一条权值为w+x的无向边。(v为L,v+n为R)
若u为M,v为L: 在u和v之间连一条权值为w的无向边。同时在u+n和v之间连一条权值为w+x的无向边。
若u为R,u为M: 在u和v之间连一条权值为w+x的无向边。同时在u和v+n之间连一条权值为w的无向边。
若u为M,u为R: 在u和v之间连一条权值为w+x的无向边。同时在u+n和v之间连一条权值为w的无向边。
若u为M,u为M: 在u和v之间连一条权值为w的无向边。 在u+n和v+n之间连一条权值为w的无向边。在u+n和v之间连一条权值为w+x的无向边。在u和v+n之间连一条权值为w+x的无向边。
代码:
#include <bits/stdc++.h>#define ll long long
using namespace std;
const ll INF=0x3f3f3f3f3f3f3f3f;
const int N=1e5+1;
typedef struct Edge{int to;ll value;}ed;
struct s1
{int q1;int we;friend bool operator <(s1 z,s1 x){return z.we>x.we;}
};
vector<ed> e[N];
int dis[100001];
int visit[100001];
char f[N];
void djstl(int s,int t,int n)
{int qd=0;if(f[s]=='M') dis[0]=0,qd=0;else dis[s]=0,qd=s;priority_queue<s1>qq;s1 node;node.q1=qd;node.we=dis[qd];qq.push(node);visit[qd]=1;while(!qq.empty()){node=qq.top();qq.pop();qd=node.q1;visit[qd]=1;for (int i=0;i<e[qd].size();i++){ed edg=e[qd][i];if(dis[edg.to]>dis[qd]+edg.value&&!visit[edg.to]){dis[edg.to]=dis[qd]+edg.value;node.q1=edg.to;node.we=dis[edg.to];qq.push(node);}}node=qq.top();while(visit[node.q1]&&!qq.empty()) qq.pop(),node=qq.top();}if(f[t]=='M') cout<<dis[2*n+1];else cout<<dis[t];
}
int main()
{ios::sync_with_stdio(0);cin.tie(0), cout.tie(0);int t;cin>>t;while(t--){int n,m,s,t,x;cin>>n>>m>>s>>t>>x;scanf("%s",f+1);for (int i=0;i<=2*n+1;i++) dis[i]=INF,visit[i]=0,e[i].clear();if(f[s]=='M'){e[s].push_back(ed{0,0});e[s+n].push_back(ed{0,0});e[0].push_back(ed{s,0});e[0].push_back(ed{s+n,0});}if(f[t]=='M'){e[t].push_back(ed{2*n+1,0});e[t+n].push_back(ed{2*n+1,0});e[2*n+1].push_back(ed{t,0});e[2*n+1].push_back(ed{t+n,0});}for (int i=0;i<m;i++){int a,b,d;cin>>a>>b>>d;if((f[a]=='L'&&f[b]=='L')||(f[a]=='R'&&f[b]=='R')){e[a].push_back(ed{b,d});e[b].push_back(ed{a,d});}if((f[a]=='L'&&f[b]=='R')||(f[a]=='R'&&f[b]=='L')){e[a].push_back(ed{b,d+x});e[b].push_back(ed{a,d+x});}if(f[a]=='L'&&f[b]=='M'){e[a].push_back(ed{b,d});e[a].push_back(ed{b+n,d+x});e[b].push_back(ed{a,d});e[b+n].push_back(ed{a,d+x});}if(f[a]=='R'&&f[b]=='M'){e[a].push_back(ed{b,d+x});e[a].push_back(ed{b+n,d});e[b].push_back(ed{a,d+x});e[b+n].push_back(ed{a,d});}if(f[a]=='M'&&f[b]=='L'){e[b].push_back(ed{a,d});e[b].push_back(ed{a+n,d+x});e[a].push_back(ed{b,d});e[a+n].push_back(ed{b,d+x});}if(f[a]=='M'&&f[b]=='R'){e[b].push_back(ed{a,d+x});e[b].push_back(ed{a+n,d});e[a].push_back(ed{b,d+x});e[a+n].push_back(ed{b,d});}if(f[a]=='M'&&f[b]=='M'){e[b].push_back(ed{a,d});e[b].push_back(ed{a+n,d+x});e[b+n].push_back(ed{a,d+x});e[b+n].push_back(ed{a+n,d});e[a].push_back(ed{b,d});e[a].push_back(ed{b+n,d+x});e[a+n].push_back(ed{b,d+x});e[a+n].push_back(ed{b+n,d});}}djstl(s,t,n);cout<<endl;}}