标签:
给你一张无向图,点数为
观察后我们可以发现,答案可以二分,那么我们就二分
然后我们就只需要知道当
然后我们分析一下发现,如果我们在已经花费了
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <cmath>
#include <algorithm>
#include <iostream>
using namespace std;
int N,M,H,S,EN;
struct bian_
{
int aim;
int next;
int T;
int R;
int P;
}bian[20010]={{0,0,0,0,0}};
int First[110]={0};
int ans=2e9;
int ansp=0;
int fa[110]={0};
int Out[110]={0};
int dist[110]={0};
int dui[810]={0};
int duip=0;
int hash[110]={0};
int E[110]={0};
void Add(int a,int b,int t,int r,int p,int k)
{
bian[k].next=First[a];
bian[k].aim=b;
bian[k].T=t;
bian[k].R=r;
bian[k].P=p;
First[a]=k;
return;
}
bool check(int Max)
{
memset(dist,-1,sizeof(dist));
duip=0;
dist[S]=0;
dui[++duip]=S;
for(int i=1;i<=duip;i++)
{
int u=dui[i];
for(int p=First[u];p!=0;p=bian[p].next)
{
int TT=dist[u]+bian[p].T;
int v=bian[p].aim;
if(dist[v]==-1) dist[v]=2147483647;
if((long long)TT*bian[p].P+bian[p].R<=(long long)Max && TT<dist[v])
{
fa[v]=u;
dist[v]=TT;
if(hash[v]==0)
{
hash[v]=1;
dui[++duip]=v;
}
}
}
hash[u]=0;
}
for(int i=1;i<=EN;i++)
{
if(dist[E[i]]!=2147483647 && dist[E[i]]!=-1)
{
ansp=0;
for(int j=E[i];j!=S;j=fa[j])
Out[++ansp]=j;
return true;
}
}
return false;
}
int main()
{
freopen("sgu240.in","r",stdin);
freopen("sgu240.out","w",stdout);
scanf("%d%d%d%d%d",&N,&M,&H,&S,&EN);
for(int i=1;i<=M;i++)
{
int a,b,t,r,p;
scanf("%d%d%d%d%d",&a,&b,&t,&r,&p);
Add(a,b,t,r,p,(i<<1)-1);
Add(b,a,t,r,p,i<<1);
}
for(int i=1;i<=EN;i++)
scanf("%d",&E[i]);
for(int L=0,R=H;L<=R;)
{
int mid=(L+R)>>1;
if(check(mid)==true)
{
ans=mid;
R=mid-1;
}
else L=mid+1;
}
if(ans==2e9)
cout<<"NO"<<endl;
else
{
cout<<"YES"<<endl;
cout<<ans<<endl;
cout<<ansp+1<<‘ ‘<<S;
for(int i=ansp;i>=1;i--)
printf(" %d",Out[i]);
cout<<endl;
}
fclose(stdin);
fclose(stdout);
return 0;
}
标签:
原文地址:http://blog.csdn.net/qq_21995319/article/details/45648757