1. 程式人生 > 遊戲 >左手翻雲右手覆雨 武俠角色扮演遊戲《俠之信條》1月26日登陸Steam

左手翻雲右手覆雨 武俠角色扮演遊戲《俠之信條》1月26日登陸Steam

目錄

題目傳送門

題目描述

題目描述

設 GG 為有 nn 個頂點的帶權有向無環圖,GG 中各頂點的編號為 11 到 nn,請設計演算法,計算圖 GG 中 1, n1,n 間的最長路徑。

輸入格式

輸入的第一行有兩個整數,分別代表圖的點數 nn 和邊數 mm

第 22 到第 (m + 1)(m+1) 行,每行 33 個整數 u, v, wu,v,w(u<vu<v),代表存在一條從 uu 到 vv 邊權為 ww 的邊。

輸出格式

輸出一行一個整數,代表 11 到 nn 的最長路。

若 11 與 nn

不連通,請輸出 -1−1。

輸入輸出樣例

輸入 #1複製

2 1
1 2 1

輸出 #1複製

1

說明/提示

【資料規模與約定】

  • 對於 20%20%的資料,n \leq 100n≤100,m \leq 10^3m≤103。
  • 對於 40%40% 的資料,n \leq 10^3n≤103,m \leq 10^{4}m≤104。
  • 對於 100%100% 的資料,1 \leq n \leq 15001≤n≤1500,1 \leq m \leq 5 \times 10^41≤m≤5×104,1 \leq u, v \leq n1≤u,vn,-10^5 \leq w \leq 10^5−105≤w≤105。

拓撲排序演算法求解

分析

如果題目不限制從1出發,到n,求到某個點的最長路徑,那麼直接進行拓撲排序,然後每次更新就可以了

但是題目說了從1到n最長路徑,那麼這個路徑之外的點都不用管,所以只更新1能到達的點的最長路徑值就可以了

  • 在拓撲排序過程中同步標記1能到的點

  • 然後所有點正常拓撲排序,但是更行1到每個點最大值的時候,只需要更新1能到的點的就行,其他1不能到達的點不用管

程式碼

#include<iostream>
#include<cstdio>
#include<algorithm>
#include<queue>
#include<vector>
#include<cstring>
using namespace std;
const int N = 1510; 
struct Edge
{
	int to;
	int w; //從該點到to點的邊的權重 
};
vector<Edge> h[N]; //存圖  
int d[N]; // 入度 
int n, m;
bool st[N]; // 標記1能到的點 為 true 
int  maxx[N]; // 從1能到該點的路徑最大值 

void add(int a, int b, int weight)
{
	Edge edge;
	edge.to = b;
	edge.w  = weight;
	h[a].push_back(edge);
} 

void tor()
{
	// q存節點編號,用int就行 
	queue<int> q;
    for(int i = 1; i <= n; i++)
    {
    	// 如果該點的入度為0,加入佇列中 
		if(!d[i]) q.push(i);
	}
	
	while(!q.empty())
	{
		int t = q.front();
		q.pop();
		
		for(int i = 0; i < h[t].size(); i++)
		{
			int j = h[t][i].to;
			int weight = h[t][i].w;
			
			// 標準拓撲操作 
			d[j]--;
			if(!d[j]) q.push(j);
			
			//  如果1能到t點 
			if(st[t])	
			{
				st[j] = true; // 那麼也一定能到j點,這個時候再更新j點的最大距離 
				maxx[j] = max(maxx[j], maxx[t] + weight); 
			}
		} 
	}
}

int main()
{
	memset(maxx, -1, sizeof maxx); // 初始化到1每個點的最大距離為-1 
	scanf("%d%d", &n, &m);
	while(m--)
	{
		int a, b, w;
		scanf("%d%d%d", &a, &b, &w);
		add(a, b, w); // a -> b
		d[b]++; // 
	}	
	
	maxx[1] = 0;
	st[1] = true; 
	tor();
	
	printf("%d\n", maxx[n]);
	return 0;
} 

時間複雜度

參考文章

https://www.luogu.com.cn/blog/AcerMo/solution-p1807