思路:
几个小问题:
- 模板准备了吗?
- dp会了吗?
- 题目懂了吗?
- [luogu]P1144 最短路计数会了吗?
代码:
#include<bits/stdc++.h>
using namespace std;
const int INF = 0x7FFFFFFF;
struct E
{
int to;
int wt;
int nxt;
};
E vedge[200005], sedge[200005];
int vtot, stot;
int vhead[100005], shead[100005];
int n, m, k, p;
int d[100005];
int ans[100005][55];
bool vis[100005][55];
bool flag[100005];
queue<int> q;
queue<int> f;
void vadd(int u, int v, int w)
{
vtot++;
vedge[vtot].to = v;
vedge[vtot].wt = w;
vedge[vtot].nxt = vhead[u];
vhead[u] = vtot;
}
void sadd(int u, int v, int w)
{
stot++;
sedge[stot].to = v;
sedge[stot].wt = w;
sedge[stot].nxt = shead[u];
shead[u] = stot;
}
int dfs(int a, int b)
{
if(b < 0)
{
return 0;
}
else
{
if(vis[a][b] == 1)
{
return -INF;
}
else
{
if(ans[a][b] != -1)
{
return ans[a][b];
}
else
{
vis[a][b] = 1;
int key = 0;
if(a == n)
{
key++;
}
for(int i = vhead[a]; i; i = vedge[i].nxt)
{
int g = vedge[i].to;
int y = vedge[i].wt;
int u = d[g] - d[a];
if(flag[g] == 0)
{
continue;
}
int w = dfs(g, b - (y - u));
if(w == -INF)
{
return -INF;
}
else
{
key = (key + w) % p;
}
}
ans[a][b] = key % p;
vis[a][b] = 0;
return key;
}
}
}
}
void _spfa()
{
f.push(n);
flag[n] = 1;
while(!f.empty())
{
int h = f.front();
f.pop();
for(int i = shead[h]; i; i = sedge[i].nxt)
{
int g = sedge[i].to;
if(flag[g] == 0)
{
flag[g] = 1;
f.push(g);
}
}
}
return;
}
void spfa()
{
q.push(1);
d[1] = 0;
while(!q.empty())
{
int h = q.front();
q.pop();
for(int i = vhead[h]; i; i = vedge[i].nxt)
{
int g = vedge[i].to;
int y = vedge[i].wt;
if(d[h] + y < d[g])
{
d[g] = d[h] + y;
q.push(g);
}
}
}
return;
}
int main()
{
ios_base::sync_with_stdio(false);
int t = 0;
cin >> t;
while(t--)
{
cin >> n >> m >> k >> p;
memset(vhead, 0, sizeof(vhead));
memset(shead, 0, sizeof(shead));
vtot = 0;
stot = 0;
memset(vedge, 0, sizeof(vedge));
memset(sedge, 0, sizeof(sedge));
for(int i = 1; i <= n; i++)
{
flag[i] = 0;
for(int l = 0; l <= k; l++)
{
ans[i][l] = -1;
vis[i][l] = 0;
}
}
for(int i = 0; i < m; i++)
{
int u = 0, v = 0, w = 0;
cin >> u >> v >> w;
vadd(u, v, w);
sadd(v, u, w);
}
for(int i = 2; i <= n; i++)
{
d[i] = INF;
}
spfa();
_spfa();
int z = dfs(1, k);
if(z == -INF)
{
cout << -1 << endl;
}
else
{
cout << z << endl;
}
}
return 0;
}