HDU 6805 Deliver the Cake(拆点重构+最短路)

题意:给出一个无向图,每个点有三种状态LRM,每个点到下一个点的时候L->R和R->L都需要额外付出x的代价,M表示都接受且不用付出额外代价。求S到T的最少代价。

题解:把状态为M的点拆成状态L的点,和状态R的两个点重新建图,跑dijkstra时候转移的时候看看是否需要付出额外的代价即可,为了方便每个点都拆分成2个点。

#include <bits/stdc++.h>
#define IO_read ios::sync_with_stdio(false);cin.tie(0)
#define fre freopen("in.txt", "r", stdin)
#define _for(i,a,b) for(int i=a; i< b; i++)
#define _rep(i,a,b) for(int i=a; i<=b; i++)
#define inf 0x3f3f3f3f
#define lowbit(a) ((a)&-(a))
using namespace std;
typedef long long ll;
template <class T>
void read(T &x)
{
    char c; bool op=0;
    while(c=getchar(), c<'0'||c>'9') if(c=='-') op=1;
    x=c-'0';
    while(c=getchar(), c>='0'&&c<='9') x=x*10+c-'0';
    if(op) x=-x;
}
template <class T>
void write(T x)
{
    if(x<0) putchar('-'), x=-x;
    if(x>=10) write(x/10);
    putchar('0'+x%10);
}

const int maxn=2e5+5;
const long long inf_ll= (ll)1<<61;
struct qnode{
    int v;
    ll c;
    qnode(int _v=0, ll _c=0):v(_v), c(_c) {}
    bool operator <(const qnode &r) const{
        return c>r.c;
    }
};

struct Edge{
    int v;
    ll cost;
    Edge(int _v=0, ll _cost=0): v(_v), cost(_cost){}
};

vector<Edge> E[maxn*4];
bool vis[maxn];
ll dis[maxn];
int pre[maxn];

int T, n, m,  s, t, x;
char str[maxn];
int lim[maxn];

void dijkstra(int n, int start)
{
    memset(vis, 0, sizeof(vis));
    for(int i=1; i<=n; i++) dis[i]=inf_ll;
    priority_queue<qnode> que;
    que.push(qnode(start, 0));
    dis[start]=0;
    while(!que.empty())
    {
        qnode tmp=que.top(); que.pop();
        int u=tmp.v;
        if(vis[u]) continue;
        vis[u]=true;
        for(int i=0; i<E[u].size(); i++)
        {
            int v=E[u][i].v;
            ll cost=E[u][i].cost;
            int ok=lim[u]==lim[v]? 0:1;
            if(!vis[v] && dis[v]>dis[u]+cost+ok*x)
            {
                dis[v]=dis[u]+cost+ok*x;
                pre[v]=u;
                que.push(qnode(v, dis[v]));
            }
        }
    }
}

void addedge(int u, int v, int w)
{
    E[u].push_back(Edge(v, w));
    E[v].push_back(Edge(u, w));
}

void build(int u, int v, int w)
{
    addedge(u, v, w);
    addedge(u+n, v, w);
    addedge(u, v+n, w);
    addedge(u+n, v+n, w);
}

int main()
{
    read(T);
    while(T--)
    {
        read(n), read(m), read(s), read(t), read(x);
        _rep(i, 1, 2*n) E[i].clear();
        scanf("%s", str+1);
        _rep(i, 1, n){
            if(str[i]=='L') lim[i]=lim[i+n]=0;
            else if(str[i]=='R') lim[i]=lim[i+n]=1;
            else lim[i]=0, lim[i+n]=1;
        }
        _rep(i, 1, m){
            int u, v, w;
            read(u), read(v), read(w);
            build(u, v, w);
        }
        long long ans=inf;
        if(str[s]=='L' || str[s]=='R'){
            dijkstra(2*n, s);
            ans=min(dis[t], dis[t+n]);
        }
        else{
            dijkstra(2*n, s);
            ans=min(dis[t], dis[t+n]);
            dijkstra(2*n, s+n);
            ans=min(ans, min(dis[t], dis[t+n]));
        }
        printf("%lld\n", ans);
    }
    return 0;
}

 

posted @ 2020-07-31 15:56  N_Yokel  阅读(189)  评论(0编辑  收藏  举报