DIJ(拆点) - Deliver the Cake - HDU 6805
2020 Multi-University Training Contest 4
题意:
输入:
输出:
Sample Input
1
3 3 1 3 100
LRM
1 2 10
2 3 10
1 3 100
Sample Output
100
数据范围:
The sum of n in all test cases doesn’t exceed 2×105. The sum of m doesn’t exceed 4×105.
分析:
如何拆点?
注意:
代码:
#include<cstring>
#include<cstdio>
#include<iostream>
#include<algorithm>
#include<cmath>
#include<queue>
#define ll long long
#define P pair<ll,int>
#define x first
#define y second
using namespace std;
const int N=2e5+10, M=2e6+10, inf=0x3f3f3f3f;
int T,n,m,s,t,x;
int e[M],ne[M],w[M],h[N],idx;
char str[N];
ll dis[N];
bool st[N];
void add(int a,int b,int c)
{
e[idx]=b,ne[idx]=h[a],w[idx]=c,h[a]=idx++;
}
int dijkstra()
{
memset(st,false,sizeof st);
memset(dis,0x3f,sizeof dis);
if(str[s]=='M') dis[0]=0;
else dis[s]=0;
priority_queue<P,vector<P>,greater<P>> heap;
if(str[s]=='M') heap.push({0,0});
else heap.push({0,s});
while(heap.size())
{
P t=heap.top();
heap.pop();
int id=t.second;
if(st[id]) continue;
st[id]=true;
for(int i=h[id];~i;i=ne[i])
{
int j=e[i];
if(dis[j]>dis[id]+w[i])
{
dis[j]=dis[id]+w[i];
heap.push({dis[j],j});
}
}
}
if(str[t]=='M') return dis[2*n+1];
return dis[t];
}
int main()
{
scanf("%d",&T);
while(T--)
{
idx=0;
memset(h,-1,sizeof h);
scanf("%d%d%d%d%d",&n,&m,&s,&t,&x);
scanf("%s",str+1);
if(str[s]=='M')
{
add(0,s,0), add(s,0,0);
add(0,s+n,0), add(s+n,0,0);
}
if(str[t]=='M')
{
add(2*n+1,t,0), add(t,2*n+1,0);
add(2*n+1,t+n,0), add(t+n,2*n+1,0);
}
int a,b,c;
for(int i=0;i<m;i++)
{
scanf("%d%d%d",&a,&b,&c);
if((str[a]=='L'&&str[b]=='R') || (str[a]=='R'&&str[b]=='L'))
{
add(a,b,c+x), add(b,a,c+x); //LR or RL
}
else if((str[a]=='L'&&str[b]=='L') || (str[a]=='R'&&str[b]=='R'))
{
add(a,b,c), add(b,a,c); //LL or RR
}
else if(str[a]=='L'&&str[b]=='M')
{
add(a,b,c), add(b,a,c); // LL
add(a,n+b,c+x), add(n+b,a,c+x); //LR
}
else if(str[a]=='M'&&str[b]=='L')
{
add(a,b,c), add(b,a,c); //LL
add(a+n,b,c+x), add(b,a+n,c+x); //RL
}
else if(str[a]=='R'&&str[b]=='M')
{
add(a,b,c+x), add(b,a,c+x); //RL
add(a,n+b,c), add(n+b,a,c); //RR
}
else if(str[a]=='M'&&str[b]=='R')
{
add(a,b,c+x), add(b,a,c+x); //LR
add(a+n,b,c), add(b,a+n,c); //RR
}
else if(str[a]=='M'&&str[b]=='M')
{
add(a,b,c), add(b,a,c); //LL
add(a,b+n,c+x), add(b+n,a,c+x); //LR
add(a+n,b,c+x), add(b,a+n,c+x); //RL
add(a+n,b+n,c), add(b+n,a+n,c); //RR
}
}
printf("%lld\n",dijkstra());
}
return 0;
}