洛谷P 1608経路統計【膜改dij】
4851 ワード
転送ドア//題意:1-nの最短ルート数を求める.
注意の1つは重辺が1本しかないので(だから私は2発waしました)、私たちは図を建てるときに重さを払う必要があります.
そして、この点までの最短ルートが何本あるかを記録する配列を開くので、dis[to]==dis[u.to]+e[i].w; このレコード配列を更新するには、ans[to]+=ans[u.to];元のdijでいくつかの小さな変化を行えばよい.AC Code
注意の1つは重辺が1本しかないので(だから私は2発waしました)、私たちは図を建てるときに重さを払う必要があります.
そして、この点までの最短ルートが何本あるかを記録する配列を開くので、dis[to]==dis[u.to]+e[i].w; このレコード配列を更新するには、ans[to]+=ans[u.to];元のdijでいくつかの小さな変化を行えばよい.AC Code
const int maxn = 2e3+5;
int cas=1;
struct node {
int to, next, w;
bool operator return w > a.w;
}
}e[maxn*maxn];
int cnt, head[maxn];
void add(int u, int v, int w) {
e[cnt] = node{v, head[u], w};
head[u] = cnt++;
}
void init() {
cnt = 0;
Fill(head, -1);
}
int dis[maxn], vis[maxn];
int ans[maxn];
void dij(int st, int ed) {
priority_queueq;
q.push(node{st, 0, 0});
Fill(dis, inf); Fill(vis, 0); Fill(ans ,0);
dis[st] = 0; ans[st] = 1;
while(!q.empty()) {
node u = q.top();
q.pop();
if (vis[u.to]) continue;
vis[u.to] = 1;
for (int i = head[u.to] ; ~i ; i = e[i].next) {
int to = e[i].to;
int d = u.w + e[i].w;
// cout << "BBB" << u.to << ' ' << to << ' ' << dis[to] << ' ' << d << ' ' << endl;
if (d < dis[to]) {
dis[to] = d;
ans[to] = ans[u.to];
q.push(node{to, 0, d});
}
else if (d == dis[to]) ans[to] += ans[u.to];
// cout << "AAA" << ans[u.to] << ' ' << ans[to] << endl;
}
}
if (dis[ed] == inf) cout << "No answer" << endl;
else printf("%d %d
", dis[ed], ans[ed]);
}
int s[maxn][maxn];
void solve()
{
int n, m;
scanf("%d%d",&n, &m);
init();
for (int i = 1 ; i <= m ; i ++) {
int u, v, w;
scanf("%d%d%d ", &u, &v, &w);
if (s[u][v] == w) continue; //
s[u][v] = w;
add(u, v, w);
}
dij(1, n);
}