这个题型现在才做真是太失败了,因为noip去年就考了及其类似的题。。
方法还是暴力中比较巧的,就是不断增广,取和和当前估价值差值最小的操作,类似dijkstra的贪心方法,一直增广到目标为止
主要思想就是利用dp的结果指导暴力,然后用堆取贪心
码:
// luogu-judger-enable-o2
#include<iostream>
#include<cstdio>
#include<queue>
#include<vector>
using namespace std;
double f[5005],e,z;
bool vis[5005];
vector<int>v[5005],v2[5005];
vector<double>c[5005],c2[5005];
int i,j,n,m,ans,x,y;
struct la
{
int o;
double g;
bool operator < (const la a)const
{
return a.g+f[a.o]<g+f[o];
}
};
void spfa()
{
queue<int>q;
for(i=1;i<=n;i++)f[i]=999999999;
f[n]=0;
q.push(n);
while(!q.empty())
{
int st=q.front();
vis[st]=0;
q.pop();
for(i=0;i<v2[st].size();i++)
{
int nd=v2[st][i];
if(f[nd]<f[st]+c2[st][i])continue;
f[nd]=f[st]+c2[st][i];
if(!vis[nd])q.push(nd),vis[nd]=1;
}
}
}
void astar()
{
priority_queue<la>q;
la o;
o.o=1;
o.g=0;
q.push(o);
while(!q.empty())
{
la st;
st=q.top();
q.pop();
if(st.o==n)
{
if(st.g<e)++ans,e-=st.g;
else return;
continue;
}
for(i=0;i<v[st.o].size();i++)
{
la nd;
nd.o=v[st.o][i];
nd.g=st.g+c[st.o][i];
q.push(nd);
}
}
}
int main()
{
scanf("%d%d%lf",&n,&m,&e);
for(i=1;i<=m;i++)
{
scanf("%d%d%lf",&x,&y,&z);
v[x].push_back(y);
c[x].push_back(z);
v2[y].push_back(x);
c2[y].push_back(z);
}
spfa();
astar();
printf("%d",ans);
}