列表

详情


NC50376. Roadblocks

描述

贝茜把家搬到了一个小农场,但她常常回到FJ的农场去拜访她的朋友。贝茜很喜欢路边的风景,不想那么快地结束她的旅途,于是她每次回农场,都会选择第二短的路径,而不象我们所习惯的那样,选择最短路。
贝茜所在的乡村有条双向道路,每条路都连接了所有的个农场中的某两个。贝茜居住在农场1,她的朋友们居住在农场N(即贝茜每次旅行的目的地)。
贝茜选择的第二短的路径中,可以包含任何一条在最短路中出现的道路,并且一条路可以重复走多次。当然第二短路的长度必须严格大于最短路(可能有多条)的长度,但它的长度必须不大于所有除最短路外的路径的长度。
一句话题意:给一张无向图,求这张图的严格次短路之长。

输入描述

输入文件的第1行为两个整数,N和R,用空格隔开;
行:每行包含三个用空格隔开的整数A、B和D,表示存在一条长度为的路连接农场A和农场B。

输出描述

输出仅一个整数,表示从农场$1$到农场$N$的第二短路的长度。

示例1

输入:

4 4
1 2 100
2 4 200
2 3 250
3 4 100

输出:

450

说明:

最短路:1 \rightarrow2 \rightarrow4(长度为100+200=300)
第二短路:1 \rightarrow2 \rightarrow3 \rightarrow4(长度为100+250+100=450)

原站题解

上次编辑到这里,代码来自缓存 点击恢复默认模板

C++(g++ 7.5.0) 解法, 执行用时: 36ms, 内存消耗: 2928K, 提交时间: 2023-08-10 17:27:36

#include<bits/stdc++.h>
#define PII pair<int,int>
#define x first
#define y second
using namespace std;
const int N = 5e3 + 10 , M = 1e5 + 10;
int h[N],e[M<<1],nxt[M<<1],w[M<<1];
int dis[N][2];
bool st[N][2];
int tot;
int n,m;
int u,v,s;
inline void add(int u,int v,int s) {
	e[++tot] = v;
	nxt[tot] = h[u];
	h[u] = tot;
	w[tot] = s;
}
inline void spfa() {
	memset(dis,0x3f,sizeof dis);
	memset(st,false,sizeof st);
	queue<PII> q;
	dis[1][0] = 0;
	q.push({1,0});
	while(q.size()) {
		auto t = q.front();
		q.pop();
		st[t.x][t.y] = false;
		for(int i = h[t.x];~i;i = nxt[i]) {
			int to = e[i];
			int d = dis[t.x][t.y] + w[i];
			if(dis[to][0] > d) {
				dis[to][1] = dis[to][0];
				dis[to][0] = d;
				if(!st[to][0]) {
					st[to][0] = true;
					q.push({to,0});
				}
				if(!st[to][1]) {
					st[to][1] = true;
					q.push({to,1});
				}
			} else if(dis[to][1] > d && dis[to][0] < d) {
				dis[to][1] = d;
				if(!st[to][1]) {
					st[to][1] = true;
					q.push({to,1});
				}
			}
		}
	}
}
int main() {
	
	ios::sync_with_stdio(false);
	cin.tie(0);
	memset(h,-1,sizeof h);
	cin>>n>>m;
	while(m--) {
		cin>>u>>v>>s;
		add(u,v,s),add(v,u,s);
	}
	spfa();
	printf("%d",dis[n][1]);
	
	return 0;
}

C++14(g++5.4) 解法, 执行用时: 115ms, 内存消耗: 3544K, 提交时间: 2019-12-28 20:29:36

#include <bits/stdc++.h>
using namespace std;

struct Edge {
  int u, v, w;
};


int main() {
  int N, R; cin >> N >> R;
  vector<Edge> edges;
  while (R--) {
    int A, B, D; cin >> A >> B >> D;
    edges.push_back(Edge{A, B, D});
    edges.push_back(Edge{B, A, D});
  }
  vector<vector<int>> D(N+1, vector<int>(2, 0x3f3f3f3f));
  D[1][0] = 0;
  for (int i = 1; i <= 2 * N; i++) {
    // for (int i = 1; i <= N; i++) cout << D[i][0] << " "; cout << endl;
    // for (int i = 1; i <= N; i++) cout << D[i][1] << " "; cout << endl;
    bool ok = true;
    for (auto e: edges) {
      if (D[e.v][0] > D[e.u][0] + e.w) {
        D[e.v][1] = D[e.v][0];
        D[e.v][0] = D[e.u][0] + e.w;
        ok = false;
      } else if (D[e.v][0] != D[e.u][0] + e.w && D[e.v][1] > D[e.u][0] + e.w) {
        D[e.v][1] = D[e.u][0] + e.w;
        ok = false;
      } 
      if (D[e.v][1] > D[e.u][1] + e.w) {
        D[e.v][1] = D[e.u][1] + e.w;
        ok = false;
      }
    }
    if (ok) break;
  }
  cout << D[N][1] << endl;
}

C++11(clang++ 3.9) 解法, 执行用时: 128ms, 内存消耗: 3672K, 提交时间: 2020-05-21 11:44:27

#include<bits/stdc++.h>
using namespace std;
struct Edge
{
	int u,v,w;
};
int main()
{
	int N,R;
	cin>>N>>R;
	vector<Edge> edges;
	while(R--)
	{
		int A,B,D;
		cin>>A>>B>>D;
		edges.push_back(Edge{A,B,D});
		edges.push_back(Edge{B,A,D});
	}
	vector<vector<int> > D(N+1,vector<int>(2,0x3f3f3f3f));
	D[1][0]=0;
	for(int i=1;i<=2*N;i++)
	{
		bool ok=true;
		for(auto e:edges)
		{
			if(D[e.v][0]>D[e.u][0]+e.w)
			{
				D[e.v][1]=D[e.v][0];
				D[e.v][0]=D[e.u][0]+e.w;
				ok=false;
			}
			else if(D[e.v][0]!=D[e.u][0]+e.w&&D[e.v][1]>D[e.u][0]+e.w)
			{
				D[e.v][1]=D[e.u][0]+e.w;
				ok=false;
			}
			if(D[e.v][1]>D[e.u][1]+e.w)
			{
				D[e.v][1]=D[e.u][1]+e.w;
				ok=false;
			}
		}
		if(ok)
		break;
	}
	cout<<D[N][1]<<endl;
}

上一题