做法:一开始就想到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; }