题意:有n个结点,m条边,每条边有一个承受值c和一个基本消耗q。通过这条边的流量不可以超过这条边的承受值。题目给定n m k表示有n个结点,m条边,k吨需要运送的货物。求把k吨货物从1运送到k要多久?
思路:最短路问题,c可以看作限定走不走这条路的一个限定值,只需要枚举每一个c并且走一次spfa就可以解决问题。这题有个要注意的地方,用long long。
#include <stdio.h>
#include <string.h>
#include <queue>
using namespace std;
#define inf 1000000000000000000LL
const long long maxn=505;
struct Node
{
long long son,next,c,l;
} edge[maxn*4];
long long head[maxn];
long long all;
long long c[maxn];
long long dis[maxn];
long long vis[maxn];
long long times[maxn];
long long n,m,k;
queue<long long>q;
void add(long long fa,long long son,long long l,long long c)
{
edge[all].son=son;
edge[all].c=c;
edge[all].l=l;
edge[all].next=head[fa]; //形成链表
head[fa]=all;//改变头节点的值。
all++;
}
long long mi(long long x,long long y)
{
return x<y?x:y;
}
long long spfa(long long c)
{
while(!q.empty())
{
q.pop();
}
memset(vis,0,sizeof(vis));
memset(times,0,sizeof(times));
q.push(1);
dis[1]=0;
for(long long i=2; i<=n; i++)
dis[i]=inf;
while(!q.empty())
{
long long u=q.front();
q.pop();
for(long long i=head[u]; i!=-1; i=edge[i].next)
{
long long v=edge[i].son;
if(edge[i].c>=c)
{
if(dis[v]>dis[u]+edge[i].l)
{
dis[v]=dis[u]+edge[i].l;
if(!vis[v])
{
q.push(v); vis[v]=1;
}
if(times[v]>n)
return inf;
}
}
}
vis[u]=0;
}
return dis[n];
}
int main()
{
while((scanf("%lld %lld %lld",&n,&m,&k))!=EOF)
{
memset(head,-1,sizeof(head));
all=0;
for(long long i=1; i<=m; i++)
{
long long tm1,tm2,tm3,tm4;
scanf("%lld %lld %lld %lld",&tm1,&tm2,&tm3,&tm4);
add(tm1,tm2,tm3,tm4);
add(tm2,tm1,tm3,tm4);
c[i]=tm4;
}
long long ans=inf;
long long tmp;
for(long long i=1; i<=m; i++)
{
tmp=spfa(c[i]);
//prlong longf("%d\n",tmp);
ans=mi(ans,tmp+k/c[i]);
}
printf("%lld\n",ans);
}
}