【好题】最短路变形+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'; }