做法:一开始就想到dijstra,可惜了...DP了解不深
#include<cstdio>
#include<cstring>
#include<queue>
#include<utility>
#include<vector>
#define eps 1e18
#define LL long long
/********
dij,其实就是一种DP思想,每一个状态(出来初始点)都会存在一个前状态,
DP需要让这些前状态都是最优的,所以dij每次要从里原点”最短“的边开始,这里的
最短,可能是长度、时间、等等。当然这里的变成了二维的条件,所以值得思考的是
什么是“最短”,嗯,用最少的小路是第一,但是,长度也必须要小。
*********/
using namespace std;
const int LMT=102;
int next[LMT],vis[LMT][5003],all,n,cs;
LL dis[LMT][5003],T;
struct path
{
int dis,time;
LL len;
};
struct cmp
{
bool operator()(path a,path b)
{
if(a.time!=b.time)return a.time>b.time;
return a.len>b.len;
}
};
struct line
{
int u,v,len,tag,next;
}e[LMT*LMT<<1];
void init(void)
{
memset(next,-1,sizeof(next));
all=0;
}
void insert(int u,int v,int len,int tag)
{
e[all].u=u;
e[all].v=v;
e[all].tag=tag;
e[all].len=len;
e[all].next=next[u];
next[u]=all++;
}
int dij(int s,int t)
{
int u,i,j,ti;
path elem,tem;
priority_queue<path,vector<path>,cmp>q;
for( i=0;i<LMT;i++)
for(j=0;j<5003;j++)dis[i][j]=eps;
memset(vis,0,sizeof(vis));
dis[s][0]=0;
elem.dis=s;
elem.time=0;
elem.len=0;
q.push(elem);
while(!q.empty())
{
elem=q.top();
q.pop();
u=elem.dis;
if(elem.len>T)continue;
if(u==t)return elem.time;
ti=elem.time;
if(vis[u][ti])continue;
vis[u][ti]=1;
for(int x=next[u];x!=-1;x=e[x].next)
if(dis[e[x].v][e[x].tag+ti]>dis[u][ti]+e[x].len)
{
dis[e[x].v][e[x].tag+ti]=dis[u][ti]+e[x].len;
tem.dis=e[x].v;tem.time=e[x].tag+ti;
tem.len=dis[u][ti]+e[x].len;
q.push(tem);
}
}
return -1;
}
int main(void)
{
int m,u,v,len,s,t,i,ans;
while(~scanf("%d%d",&n,&m))
{
init();
while(m--)
{
scanf("%d%d%d",&u,&v,&len);
insert(u,v,len,0);
insert(v,u,len,0);
}
scanf("%d",&cs);
for(i=0;i<cs;i++)
{
scanf("%d%d%d",&u,&v,&len);
insert(u,v,len,1);
insert(v,u,len,1);
}
scanf("%d%d%I64d",&s,&t,&T);
ans=dij(s,t);
if(ans==-1)printf("Impossible\n");
else printf("%d\n",ans);
}
return 0;
}