P1608 路径统计
跟模板题是不是神似??
把模板题粘过来改了改发现你WA了,为啥?
首先观察数据范围,\(E\leq N \times(N-1)\),也就是每个点都可能会有\(N-1\)条边。那么我们就避免不了有重边的情况。根据题意,重边是不应该算在内的。
而在这里我们应该去掉的是相同权值相同终起点的边。其他的边我们应该保留。因为对于同一个终点起点,只有相同权值的边会对答案产生影响。
如何去重?STL大法好。
if(find(v[x].begin(), v[x].end(), make_pair(y,z)) == v[x].end()) v[x].push_back(make_pair(y,z));
这样就算是去重了,虽然不吸氧会T一个点吧qaq。
find()函数是在vector给定的区间内查询一个数,复杂度是log的,如果找到了该元素则返回元素的迭代器,如果没有找到该元素返回的则是end()。
代码:
#include <bits/stdc++.h>
using namespace std;
template<typename temp>void read(temp &x){
x = 0;temp f = 1;char ch;
while(!isdigit(ch = getchar())) (ch == '-') and (f = -1);
for(x = ch^48; isdigit(ch = getchar()); x = (x<<1)+(x<<3)+(ch^48));
x *= f;
}
template <typename temp, typename ...Args>void read(temp& a, Args& ...args){read(a), read(args...);}
const int maxn = 2010;
int n, m, cnt, dis[maxn], head[maxn], vis[maxn], f[maxn];
vector<pair<int,int> > v[maxn];
inline void qwq(){return;}
void Dijkstra(){
for(int i = 1; i <= n; i ++) dis[i] = 1<<29;
priority_queue<pair<int,int>, vector<pair<int,int> >, greater<pair<int,int> > > q;
q.push(make_pair(0,1));
dis[1] = 0, f[1] = 1;
while(q.size()){
int now = q.top().second, len = q.top().first;
q.pop();
if(vis[now]) continue;
vis[now] = 1;
for(int i = 0; i < v[now].size(); i ++){
int to = v[now][i].first, length = v[now][i].second;
if(dis[to] > len + length){
dis[to] = len + length;
f[to] = f[now];
q.push(make_pair(dis[to],to));
}
else if(dis[to] == len + length) f[to] += f[now];
}
}
return qwq();
}
signed main(){
read(n, m);
for(int i = 1, x, y, z; i <= m; i ++){
read(x, y, z);
if(find(v[x].begin(), v[x].end(), make_pair(y,z)) == v[x].end()) v[x].push_back(make_pair(y,z));
}
Dijkstra();
if(dis[n] == 1<<29) printf("No answer");
else printf("%d %d", dis[n], f[n]);
return 0;
}