【最短路】 codeforces 449B Jzzhu and Cities

直接把火车建在图上,把所有的边加到图上,求出1号点到其他所有点的单源最短路,并记录每个点的入度。。。然后挨个检查每个火车,如果火车的路大于最短路,那么条火车路肯定是多余的。如果相等,就看入度是不是大于1,如果大于1那么这条路就是多余的。。注意最大值INF的取值不要太小。。。

#include <iostream>  
#include <queue>  
#include <stack>  
#include <map>  
#include <set>  
#include <bitset>  
#include <cstdio>  
#include <algorithm>  
#include <cstring>  
#include <climits>  
#include <cstdlib>
#include <cmath>
#define maxn 200005
#define eps 1e-10
#define mod 1000000009
#define INF 1e17  
#define lowbit(x) (x&(-x))  
#define lson o<<1, L, mid  
#define rson o<<1 | 1, mid+1, R  
typedef long long LL;
using namespace std;

struct Edge
{
	LL from, to, dist;
};
struct node
{
	LL d, u;
	bool operator < (const node &a) const {
		return a.d<d;
	}
};
struct Dijstra
{
	LL n, m;
	priority_queue<node> q;
	node tmp, now;
	Edge e;
	vector<Edge> edges;
	vector<LL> G[maxn];
	bool done[maxn];
	LL dis[maxn];
	LL in[maxn];
	void init(void)
	{
		edges.clear();
		memset(in, 0, sizeof in);
		memset(done, 0, sizeof done);
		for(int i = 0; i < maxn; i++)
			G[i].clear();
	}
	void addedge(int from, int to, int dist)
	{
		e.from = from, e.to = to, e.dist = dist;
		edges.push_back(e);
		m = edges.size();
		G[from].push_back(m-1);
	}
	void dijstra(int s)
	{
		for(int i = 0; i <= n; i++) dis[i] = INF;
		dis[s] = 0;
		tmp.u = s, tmp.d = 0;
		q.push(tmp);
		while(!q.empty()) {
			now = q.top();
			q.pop();
			if(done[now.u]) continue;
			done[now.u] = true;
			int d = G[now.u].size();
			for(int i = 0; i < d; i++) {
				Edge& e = edges[G[now.u][i]];
				if(dis[e.to] == dis[now.u] + e.dist)
					in[e.to]++;
				if(dis[e.to] > dis[now.u] + e.dist) {
					dis[e.to] = dis[now.u] + e.dist;
					in[e.to] = 1;
					tmp.u = e.to, tmp.d = dis[e.to];
					q.push(tmp);
				}
			}
		}
	}
}tmp;

struct opr
{
	LL v, dist;
}op[maxn];
void debug(void)
{
	for(int i = 1; i <= tmp.n; i++) {
		printf("%I64d\n", tmp.in[i]);
	}
}
int main(void)
{
	LL m, k, u, v, dist, ans = 0;
	scanf("%I64d%I64d%I64d", &tmp.n, &m, &k);
	for(int i = 0; i < m; i++) {
		scanf("%I64d%I64d%I64d", &u, &v, &dist);
		tmp.addedge(u, v, dist);
		tmp.addedge(v, u, dist);
	}
	for(int i = 0; i < k ; i++) {
		scanf("%I64d%I64d", &op[i].v, &op[i].dist);
		tmp.addedge(1, op[i].v, op[i].dist);
	}
	tmp.dijstra(1);
	for(int i = 0; i < k; i++) {
		if(op[i].dist == tmp.dis[op[i].v]) if(tmp.in[op[i].v] > 1) ans++, tmp.in[op[i].v]--;
		if(op[i].dist > tmp.dis[op[i].v]) ans++;
	}
	printf("%I64d\n", ans);
	return 0;
}


你可能感兴趣的:(codeforces)