Chào mọi người,
Mình loay hoay bài này hơn tuần rồi mà không có kết quả.
Chi tiết tại đây: http://vn.spoj.com/status/NK05DSRT/
Còn đây là đề bài: http://vn.spoj.com/problems/NK05DSRT/
Và đây là ý tưởng của mình:
- Sử dụng Dijkstra ngược từ đỉnh N về đỉnh 1.
#include <bits/stdc++.h>
using namespace std;
int main()
{
#ifdef gsdt
freopen("input.txt","r",stdin);
#endif // gsdt
int T;
scanf("%d",&T);
while(T--)
{
int n,c,m;
int a[220][220];
int l[220][220];
memset(a,0,sizeof(a));
memset(l,0,sizeof(l));
scanf("%d%d%d",&n,&m,&c);
assert(0<n && n<=200);
assert(0<c && c<=200);
assert(0<m && m<=200);
for(int i=1; i<=m; i++)
{
int x,y,w;
scanf("%d%d%d",&x,&y,&w);
if(w>c) continue;
a[x][++a[x][0]]=y;
a[y][++a[y][0]]=x;
l[x][y]=w;
l[y][x]=w;
}
int64_t dp[220];
bool fr[220];
memset(fr,true,sizeof(fr));
for(int i=0; i<220; i++) dp[i]=LLONG_MAX ;
dp[n]=0;
while(true)
{
int64_t u=0,MIN=LLONG_MAX ;
for(int i=1; i<=n; i++)
if(dp[i]<MIN && fr[i])
MIN=dp[i],
u=i;
if(u==1) break;
fr[u]=false;
for(int i=1; i<=a[u][0]; i++)
{
int64_t v=a[u][i];
if(!fr[v])continue;
int64_t need=dp[u];
int64_t L=l[u][v];
int64_t water;
for(int j=0; j<=1000; j++)
{
if(j!=0 && c-2*L<=0) break;
int y=need-j*(c-2*L);
if(y<0)break;
if(y+L<=c)
{
water=c*j+y+L;
assert(0<water && water<LLONG_MAX);
dp[v]=min(dp[v],water);
//break;
}
}
}
}
if(dp[1]==LLONG_MAX ) printf("NO\n");
cout<<dp[1]<<endl;
}
}
Rất mong các cao thủ vào giúp đỡ.
@david15894 @Gio