【好题】最短路变形+dp——ICPC NCNA 2018G

#include<bits/stdc++.h>
using namespace std;
#define ll long long 

struct Edge{
    ll to,nxt,w,c;
}e[10005];
int n,m,k1,k2,tot,head[1005],S,T;
void init(){
    memset(head,-1,sizeof head);
}
void add(ll u,ll v,ll w,ll c){
    e[tot].to=v;e[tot].c=c;e[tot].w=w;e[tot].nxt=head[u];head[u]=tot++;
}

map<pair<ll,ll>,ll> vis[505];
map<pair<ll,ll>,ll> d[505];
struct Node{
    ll w,id,r,b;    
    Node(){}
    Node(ll id,ll w,ll r,ll b):id(id),w(w),r(r),b(b){}
    bool operator>(Node a)const{
        return w>a.w;
    }
};
priority_queue<Node,vector<Node>,greater<Node>>pq;
void dij(){
    for(int i=1;i<=n;i++)
        for(int j=0;j<=k1;j++)
            for(int k=0;k<=k2;k++)
                d[i][make_pair(j,k)]=0x3f3f3f3f3f3f3f3f;
                
    d[S][make_pair(0,0)]=0;
    pq.push(Node(S,0,0,0));
    
    while(pq.size()){
        //for(auto x:pq)cout<<x.w<<" "<<x.id<<'\n';
        Node now=pq.top();pq.pop();
        ll u=now.id,w=now.w,r=now.r,b=now.b;
        if(vis[u][make_pair(r,b)]==1)continue;
        vis[u][make_pair(r,b)]=1;
        for(int i=head[u];i!=-1;i=e[i].nxt){
            int v=e[i].to,c=e[i].c,R=r,B=b;            
            if(c==1)R++;
            else if(c==2)B++;            
            if(R>k1 || B>k2 || vis[v][make_pair(R,B)]==1)continue;
            if(d[v][make_pair(R,B)]>w+e[i].w){
                d[v][make_pair(R,B)]=w+e[i].w;
                pq.push(Node(v,w+e[i].w,R,B));
            }
        }
    }
}

int main(){
    init();
    cin>>n>>m>>k1>>k2;
    for(int i=1;i<=m;i++){
        ll u,v,x,c;
        scanf("%lld%lld%lld%lld",&u,&v,&x,&c);
        add(u,v,x,c);
        add(v,u,x,c);
    }
    cin>>S>>T;
    dij();
    if(d[T][make_pair(k1,k2)]==0x3f3f3f3f3f3f3f3f)
        cout<<-1<<'\n';
    else cout<<d[T][make_pair(k1,k2)]<<'\n';
}

猜你喜欢

转载自www.cnblogs.com/zsben991126/p/12805747.html