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;
}
posted @ 2020-08-02 21:50  Vanyun  阅读(124)  评论(3编辑  收藏  举报