分層圖,dp。本題求的是多少種方案,不是多少個路徑。。。
dp[i][j]表示到第i點時用了j時間所花的錢數。
注意:走過最長的路徑是(n-1)*100,否則會爆!!!
#include<stdio.h>
#include<string.h>
#include<stdlib.h>
#include<queue>
#include<algorithm>
using namespace std;
#define inf 2050
typedef long long ll;
int n,m,s,e;
int maxn;
struct node
{
int to,next,len,val;
}edge[2050];
int head[1000];
int cnt;
void add(int f,int t,int l,int v)
{
edge[cnt].to=t;
edge[cnt].len=l;
edge[cnt].val=v;
edge[cnt].next=head[f];
head[f]=cnt++;
}
struct nn
{
int mon,sum;
}dp[105][10005];
struct mm
{
int pos,dis;
};
queue<mm>Q;
int vis[105][10005];
int min_val=0x3f3f3f3f;
int ans;
void dij()
{
for(int i=1;i<=n;i++)
{
for(int j=0;j<=30005;j++)
{
dp[i][j].mon=0x3f3f3f3f;
dp[i][j].sum=0;
}
}
dp[s][0].mon=0;
dp[s][0].sum=1;
vis[s][0]=1;
mm st;
st.pos=s;
st.dis=0;
Q.push(st);
while(!Q.empty())
{
mm u=Q.front();
Q.pop();
vis[u.pos][u.dis]=0;
for(int i=head[u.pos];i!=-1;i=edge[i].next)
{
if(u.dis+edge[i].len>maxn+1)continue;
if(dp[u.pos][u.dis].mon+edge[i].val<dp[edge[i].to][u.dis+edge[i].len].mon)
{
dp[edge[i].to][u.dis+edge[i].len].mon=dp[u.pos][u.dis].mon+edge[i].val;
dp[edge[i].to][u.dis+edge[i].len].sum=1;
if(vis[edge[i].to][u.dis+edge[i].len]==0)
{
mm vv;
vv.pos=edge[i].to;
vv.dis=u.dis+edge[i].len;
vis[edge[i].to][u.dis+edge[i].len]=1;
Q.push(vv);
}
}
}
}
}
int main()
{
scanf("%d %d %d %d",&n,&m,&s,&e);
memset(head,-1,sizeof(head));
for(int i=1;i<=m;i++)
{
int a,b,c,d;
scanf("%d %d %d %d",&a,&b,&c,&d);
add(a,b,c,d);
add(b,a,c,d);
}
maxn=(n-1)*100;
dij();
for(int i=0;i<=maxn+5;i++)
{
if(!dp[e][i].sum)continue;
if(dp[e][i].mon<min_val)//時間長但錢數少
{
ans++;
min_val=dp[e][i].mon;
}
}
printf("%d",ans);
}