【链接】
libreoj6177
【解题报告】
其实就是简单的状压DP。
定义
fi,j
表示目前在第
i
个点,
然后就很好写了。
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
const int maxn=25,maxv=59055;
int n,m,Q,ans,INF,g[maxn][maxn],s[maxn],t[maxn],l[maxn],r[maxn],p[maxn],f[maxn][maxv];
inline int Read()
{
int res=0;
char ch=getchar();
while (ch<'0'||ch>'9') ch=getchar();
while (ch>='0'&&ch<='9') res=res*10+ch-48,ch=getchar();
return res;
}
int main()
{
freopen("6177.in","r",stdin);
freopen("6177.out","w",stdout);
n=Read(); m=Read(); Q=Read(); ans=0;
memset(g,63,sizeof(g)); INF=g[0][0];
for (int i=1; i<=n; i++) g[i][i]=0;
for (int i=1,x,y,z; i<=m; i++) x=Read(),y=Read(),z=Read(),g[x][y]=min(g[x][y],z);
for (int k=1; k<=n; k++)
for (int i=1; i<=n; i++)
for (int j=1; j<=n; j++)
g[i][j]=min(g[i][j],g[i][k]+g[k][j]);
for (int i=0; i<Q; i++) s[i]=Read(),t[i]=Read(),l[i]=Read(),r[i]=Read();
p[0]=1; for (int i=1; i<=Q; i++) p[i]=p[i-1]*3;
memset(f,63,sizeof(f)); f[1][0]=0;
for (int k=0; k<p[Q]; k++)
for (int i=1; i<=n; i++)
if (f[i][k]!=INF)
{
int tot=0;
for (int j=0; j<Q; j++)
{
int w=k/p[j]%3;
if (w==0) f[s[j]][k+p[j]]=min(f[s[j]][k+p[j]],max(f[i][k]+g[i][s[j]],l[j]));
else if (w==1) {if (f[i][k]+g[i][t[j]]<=r[j]) f[t[j]][k+p[j]]=min(f[t[j]][k+p[j]],f[i][k]+g[i][t[j]]);}
else tot++;
}
ans=max(ans,tot);
}
printf("%d\n",ans);
return 0;
}