#include<iostream>
#include<cstdio>
#include<cstring>
#include<queue>
#define ll long long
using namespace std;
int n,m,k,e;
int d;
ll v[25];
bool no[25];
ll f[110];
int head[25],ver[410],nnext[410];
int tot;
ll c[410];
int a[25],b[25];
void add(int x,int y,int z){
ver[++tot]=y;
nnext[tot]=head[x];
head[x]=tot;
c[tot]=z;
}
struct node{
ll v;
int u;
};
struct cmp{
bool operator()(node a,node b){
return a.v>b.v;
}
};
priority_queue<node,vector<node>,cmp> q;
ll diji(int x,int y){
while(!q.empty()) q.pop();
memset(v,0x3f,sizeof v);
memset(no,0,sizeof no);
v[1]=0;
q.push({0,1});
while(!q.empty()){
node u=q.top();
q.pop();
if(no[u.u]) continue;
if(u.u==m) return v[m];
no[u.u]=1;
for(int i=head[u.u];i;i=nnext[i]){
int ve=ver[i];
if((x<=a[ve]&&y>=a[ve])||(x<=b[ve]&&y>=b[ve])||(x>=a[ve]&&y<=b[ve])||(x<=a[ve]&&y>=b[ve])) continue;//***
/* bool fl=0;
for(int j=x;j<=y;++j){
for(int k=a[ve];k<=b[ve];++k){
if(j==k){
fl=1;
break;
}
}
if(fl) break;
}
if(fl) continue;*/
// if(max(x,a[ve])<=min(y,b[ve])) continue;
if(v[u.u]+c[i]<v[ve]){
v[ve]=v[u.u]+c[i];
q.push({v[ve],ve});
}
}
}
return v[m]==0x3f3f3f3f3f3f3f3f?-1:v[m];
}
int main(){
scanf("%d%d%d%d",&n,&m,&k,&e);
for(int i=1;i<=e;++i){
int x,y;
ll z;
scanf("%d%d%lld",&x,&y,&z);
add(x,y,z);
add(y,x,z);
}
scanf("%d",&d);
for(int i=1;i<=d;++i){
int p,x,y;
scanf("%d%d%d",&p,&x,&y);
a[p]=x;
b[p]=y;
}
// puts("");
memset(f,0x3f,sizeof f);
f[0]=0;
// cout<<diji(1,4)<<endl;
for(int i=1;i<=n;++i){
ll dd=diji(1,i);
if(dd!=-1)f[i]=dd*i;
for(int j=1;j<i;++j){
ll di=diji(j+1,i);
if(di==-1) continue;
f[i]=min(f[i],f[j]+(i-j)*di+k);
// cout<<j<<" "<<i<<" "<<f[i]<<" "<<f[j]<<" "<<diji(j+1,i)<<endl;
}
}
printf("%lld\n",f[n]);
return 0;
}
上面注释*** 的那行判断节点能否用的方法为啥wa??
谢谢dalao们