1975: [Sdoi2010]魔法猪学院
Time Limit: 10 Sec Memory Limit: 64 MBSubmit: 1196 Solved: 387
[ Submit][ Status][ Discuss]
Description
Input
Output
Sample Input
1 2 1.5
2 1 1.5
1 3 3
2 3 1.5
3 4 1.5
1 4 1.5
Sample Output
HINT
样例解释
有意义的转换方式共4种:
1->4,消耗能量 1.5
1->2->1->4,消耗能量 4.5
1->3->4,消耗能量 4.5
1->2->3->4,消耗能量 4.5
显然最多只能完成其中的3种转换方式(选第一种方式,后三种方式仍选两个),即最多可以转换3份样本。
如果将 E=14.9 改为 E=15,则可以完成以上全部方式,答案变为 4。
数据规模
占总分不小于 10% 的数据满足 N <= 6,M<=15。
占总分不小于 20% 的数据满足 N <= 100,M<=300,E<=100且E和所有的ei均为整数(可以直接作为整型数字读入)。
所有数据满足 2 <= N <= 5000,1 <= M <= 200000,1<=E<=107,1<=ei<=E,E和所有的ei为实数。
解题思路:
K短路的模板题。A*
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<iostream>
using namespace std;
int n,m;
double eg;
int len=0;
const int maxn=5001;
int sum=1;
bool bb[5011];
int q[5011];
double dis[5011];
int h[5011];
struct data
{
int to,next;
double v;
}e[410001];
struct messi
{
int now;
double cost,f;
}xvier[2500000];
int x[200011];
int y[200011];
double z[200011];
void spfa()
{
memset(bb,true,sizeof(bb));
int tail=1; int head=0; q[tail]=n; dis[n]=0;
while (tail!=head)
{
head=(head+1)%maxn;
int u=h[q[head]];
while (u!=0)
{
if (dis[e[u].to]>dis[q[head]]+e[u].v)
{
dis[e[u].to]=dis[q[head]]+e[u].v;
if (bb[e[u].to])
{
bb[e[u].to]=false;
tail=(tail+1)%maxn; q[tail]=e[u].to;
}
}
u=e[u].next;
}
bb[q[head]]=true;
}
}
void push(int now,double cost,double f)
{
++sum; xvier[sum].now=now; xvier[sum].cost=cost; xvier[sum].f=f;
int x=sum;
while (x>1)
{
if (xvier[x].f<xvier[x/2].f)
{
swap(xvier[x],xvier[x/2]);
x=x/2;
}else break;
}
}
void pop()
{
--sum; xvier[1]=xvier[sum+1];
int x=1;
while (x*2<=sum)
{
int u;
if (x*2+1>sum || xvier[x*2].f<xvier[x*2+1].f)
{
u=x*2;
}else
u=x*2+1;
if (xvier[x].f>xvier[u].f)
{
swap(xvier[x],xvier[u]);
}else break;
x=u;
}
}
void insert(int x,int y,double z)
{
++len; e[len].to=y; e[len].v=z; e[len].next=h[x]; h[x]=len;
}
int main()
{
scanf("%d %d %lf",&n,&m,&eg); len=0;
for (int i=1;i<=m;++i)
{
scanf("%d %d %lf",&x[i],&y[i],&z[i]);
insert(y[i],x[i],z[i]);
}
memset(dis,0x7f,sizeof(dis));
spfa();
memset(h,0,sizeof(h)); len=0;
for (int i=1;i<=m;++i)
{
insert(x[i],y[i],z[i]);
}
int ans=0;
xvier[sum].now=1; xvier[sum].cost=0; xvier[sum].f=dis[1];
int ma=-1;
while (sum!=0)
{
if (xvier[1].now==n)
{
if (xvier[1].cost<=eg)
{
eg-=xvier[1].cost;
++ans;
}else
{
cout<<ans;
return 0;
}
pop();
continue;
}
messi zan=xvier[1]; pop();
int u=h[zan.now];
while (u!=0)
{
push(e[u].to,zan.cost+e[u].v,zan.cost+e[u].v+dis[e[u].to]);
u=e[u].next;
}
}
cout<<ans;
}