1003 Emergency

 Dijkstra:

#include<stdio.h>
int n, m, e[510][510] = { 0 }, c1, c2, inf = 99999999, p[510];
int main(void) {
	int i, j,a, b, c;
	scanf("%d%d%d%d", &n, &m, &c1, &c2);
	for (i = 0; i <= n - 1; i++)
		for (j = 0; j <= n - 1; j++) {
			if (i == j)
				e[i][j] = 0;
			else
				e[i][j] = inf;
		}
	for (i = 0; i <= n - 1; i++)
		scanf("%d", &p[i]);
	for (i = 1; i <= m; i++) {
		scanf("%d%d%d", &a, &b, &c);
		e[a][b] = c;
		e[b][a] = c;
	}
	int dis[510], people[510], min = inf, book[510] = { 0 }, path[510] = {0},u,v;
	for (i = 0; i <= n; i++) 
		dis[i] = e[c1][i];
    people[c1] = p[c1];
	path[c1] = 1;
	for (i = 1; i <= n - 1; i++) {
		min = inf;
		for (j = 0; j <= n - 1; j++)
			if (dis[j] < min && book[j] == 0) {
				u = j;
				min = dis[j];
			}
		book[u] = 1;
		for (v = 0; v <= n - 1; v++)
			if (e[u][v] < inf&&book[v]==0) {
				if (dis[v] > dis[u] + e[u][v]) {
					dis[v] = dis[u] + e[u][v];
					path[v] = path[u];
					people[v] = people[u] + p[v];
					continue;
				}
				if (dis[v] == dis[u] + e[u][v]) {
					path[v] += path[u];
					people[v] = (people[v] >= people[u] + e[u][v]) ? people[v] : people[u] + p[v];
					continue;
				}
			}
	}
	printf("%d %d",path[c2],people[c2]);
	return 0;
}

 Dijkstra堆优化:

#include<iostream>
#include<queue>
#include<vector>
#define inf 0x3fffffff
using namespace std;
struct temp {
	int a;//dis[b]
	int b;//城市号
	friend bool operator <(temp x, temp y) {
		if (x.a != x.b)
			return x.a > y.a;
		else
			return x.b < y.b;
	}
};
int main(void) {
	int n, m,c1,c2,i,k,j;
	cin >> n >> m >> c1 >> c2;
	vector<int>u, v, w, next,first(n,-1),dis(n,inf),people,sr(n),sp(n);
	vector<bool>vis(n,false);
	priority_queue<temp> mh;
	for (i = 0; i < n; i++) {
		cin >> k;
		people.push_back(k);
	}
	j = 0;
	for (i = 0; i < m; i++) {
		int a, b, c;
		cin >> a >> b >> c;
		u.push_back(a);
		v.push_back(b);
		w.push_back(c);
		next.push_back(first[a]);
		first[a] = j;
		j++;
		u.push_back(b);
		v.push_back(a);
		w.push_back(c);
		next.push_back(first[b]);
		first[b] = j;
		j++;
	}
	dis[c1] = 0;
	sr[c1] = 1;
	sp[c1] = people[c1];
	mh.push({dis[c1],c1});
	while (mh.size()) {
		int node = mh.top().b;
		mh.pop();
        if(vis[node])
			continue;
		for (i = first[node]; i != -1; i = next[i]) {
			if (dis[v[i]] > dis[u[i]] + w[i]){
				dis[v[i]] = dis[u[i]] + w[i];
				mh.push({ dis[v[i]],v[i] });
				sp[v[i]] = sp[u[i]] + people[v[i]];
				sr[v[i]] = sr[u[i]];
			}
			else if (dis[v[i]] == dis[u[i]] + w[i]) {
				sp[v[i]] = (sp[v[i]] > sp[u[i]] + people[v[i]]) ? sp[v[i]] : sp[u[i]] + people[v[i]];
				sr[v[i]] += sr[u[i]];
			}
		}
		vis[node] = true;
	}
	cout << sr[c2]<<" "<<sp[c2];
	return 0;
}

DFS:

#include<stdio.h>
int n, m, e[510][510] = { 0 }, c1, c2, inf = 99999999, p[510], min = inf, book[510] = { 0 }, sc,sump,max=0;
void dfs(int cur, int dis) {
	int i;
	if (dis > min)
		return;
	if (cur == c2) {
		if (dis < min) {
			min = dis;
			sc = 1;
			max = sump;
			return;
		}
		if (dis == min) {
			sc++;
			if (max < sump)
				max = sump;
			return;
		}
		return;
	}
	for (i = 0; i <= n - 1; i++) {
		if (!book[i] && e[cur][i] != inf) {
			book[i] = 1;
			sump += p[i];
			dfs(i, dis + e[cur][i]);
			book[i] = 0;
			sump -= p[i];
		}
	}
	return;
}
int main(void) {
	int i, j, a, b, c;
	scanf("%d%d%d%d", &n, &m, &c1, &c2);
	for (i = 0; i <= n - 1; i++)
		for (j = 0; j <= n - 1; j++) {
			if (i == j)
				e[i][j] = 0;
			else
				e[i][j] = inf;
		}
	for (i = 0; i <= n - 1; i++)
		scanf("%d", &p[i]);
	for (i = 1; i <= m; i++) {
		scanf("%d%d%d", &a, &b, &c);
		e[a][b] = c;
		e[b][a] = c;
	}
	book[c1] = 1;
	sump = p[c1];
	dfs(c1, 0);
	printf("%d %d", sc, max);
	return 0;
}

Bellman Ford+DFS:

#include<iostream>
#include<vector>
#define inf 0x3fffffff
using namespace std;
int q, c1, c2, n, m, sr = 0,sp=0,t;
vector<int>people;
void dfs(int cur, int dist, vector<bool>book, vector<int>u, vector<int>v, vector<int>w, vector<int>first, vector<int>next) {
	int i, j;
	if (dist > q)
		return;
	if (cur == c2 && dist == q) {
		sr++;
		if (sp < t)
			sp = t;
		return;
	}
	for (i = 0; i < n; i++)
		if (!book[i]) {
			for (j = first[cur]; j != -1; j = next[j])
				if (v[j] == i)
					break;
			if (j == -1)
				continue;
			t += people[i];
			book[i] = true;
			dfs(i, dist + w[j], book, u, v, w, first, next);
			t -= people[i];
			book[i] = false;
		}
	return;
}
int main(void) {
	int i, k, j;
	cin >> n >> m >> c1 >> c2;
	vector<bool>book(n, false);
	vector<int>dis(n, inf);
	vector<int>u, v, w, next, first(n, -1);
	for (i = 0; i < n; i++) {
		cin >> k;
		people.push_back(k);
	}
	j = 0;
	for (i = 0; i < m; i++) {
		int a, b, c;
		cin >> a >> b >> c;
		u.push_back(a);
		v.push_back(b);
		w.push_back(c);
		next.push_back(first[a]);
		first[a] = j;
		j++;
		u.push_back(b);
		v.push_back(a);
		w.push_back(c);
		next.push_back(first[b]);
		first[b] = j;
		j++;
	}
	dis[c1] = 0;
	t = people[c1];
	for (j = 1; j <= n - 1; j++) 
		for (i = 1; i <= 2*m; i++) 
			if (dis[v[i]] > dis[u[i]] + w[i]) {
				dis[v[i]] = dis[u[i]] + w[i];
			}
	q = dis[c2];
	book[c1] = true;
	dfs(c1, 0, book, u, v, w, first, next);
	cout << sr << " " << sp;
	return 0;
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值