我刚开始用dp做,超时了,看了别人博客重写ac的。
个人觉得此题更偏向搜索,dp数组只是记录最佳状态的标记。
#include<iostream>
#include<cstdio>
#include<cmath>
#include<map>
#include<queue>
#include<vector>
#include<cstring>
#include<algorithm>
#define rep(i,a,b) for(int i=(a);i<(b);i++)
#define rev(i,a,b) for(int i=(a);i>=(b);i--)
#define clr(a,x) memset(a,x,sizeof a)
#define inf 0x3f3f3f3f
using namespace std;
const double exxp=0.0000001;
const int maxn=1010;
const int maxm=20005;
int first[maxn],nex[maxm],w[maxm],v[maxm],vw[maxn];
int inq[maxn][105],dp[maxn][105];
int n,m,ecnt;
double mid;
struct node
{
int x,full,w;
node(int xx,int f,int ww=0)
{
x=xx,full=f,w=ww;
}
bool operator<(const node &a)const
{
return a.w<w;
}
};
int bfs(int full,int s,int t)
{
priority_queue<node>q;
while(!q.empty()) q.pop();
clr(dp,0x3f);
clr(inq,0);
q.push(node(s,0,0));
dp[s][0]=0;
while(!q.empty())
{
node e=q.top();q.pop();
int u=e.x,f=e.full;
if(u==t)return e.w;
if(inq[u][f])continue;
inq[u][f]=1;
if(f+1<=full&&!inq[u][f+1]&&dp[u][f+1]>e.w+vw[u])
{
dp[u][f+1]=e.w+vw[u];
q.push(node(u,f+1,e.w+vw[u]));
}
for(int p=first[u];~p;p=nex[p])
{
int t=v[p],k=f-w[p];
if(k>=0&&!inq[t][k]&&e.w<dp[t][k])
{
q.push(node(t,k,e.w));
dp[t][k]=e.w;
}
}
}
return inf;
}
void add_(int a,int b,int c)
{
v[ecnt]=b;
w[ecnt]=c;
nex[ecnt]=first[a];
first[a]=ecnt++;
}
int main()
{
int a,b,c;
while(~scanf("%d%d",&n,&m))
{
clr(first,-1);ecnt=0;
for(int i=0;i<n;i++)
scanf("%d",&vw[i]);
for(int i=0;i<m;i++)
{
scanf("%d%d%d",&a,&b,&c);
add_(a,b,c),add_(b,a,c);
}
scanf("%d",&m);
while(m--)
{
scanf("%d%d%d",&a,&b,&c);
int ans=bfs(a,b,c);
if(ans!=inf)printf("%d\n",ans);
else puts("impossible");
}
}
return 0;
}