P3008 [USACO11JAN] Roads and Planes G

P3008

连通块统计后,形成DAG

核心解法

解法深研思未休,

图论算法解绸缪。
负权路径何所惧,
拓扑排序定风流。

cpp 复制代码
/*
解法深研思未休,
图论算法解绸缪。
负权路径何所惧,
拓扑排序定风流。
*/
#include<bits/stdc++.h>
using namespace std;
int INF = 1e9+7; 
int n,r,p,s;
int d[100100];//所属连通块
int dis[100010];
bool vis[100010];
queue<int> t;//拓扑排序 
vector<int> block[25010];//连通块点集 
int pd[100100];//是否为顶点; 
int in[100100],tot;
struct ede{
	int v,w;
	bool operator <(const ede a)const{
		return w > a.w;
	}
};
vector<ede> g[100010];
void dfs(int u,int t) {//染色 
	if(d[u])return;
	d[u] = t; 
	block[t].push_back(u);
	for(ede vis:g[u]){
		int v = vis.v;
		dfs(v,t);
	}
}
void dijk(int s){//对连通块 S 进行dijk
	priority_queue<ede> q;
	for(int v:block[s]){
	 	if(pd[v]){
	 	  //  cout<<" "<<v<<" "<<dis[v]<<endl;
	 		q.push({v,dis[v]});
		}
	}
	while(!q.empty()){
		ede tp = q.top();
		q.pop();
		int u = tp.v;
		if(vis[u])continue;
		vis[u] = 1;
		//cout<<u<<endl;
		for(ede vised:g[u]){
			int v = vised.v,w = vised.w;
			//cout<<u<<" "<<v<<" "<<w<<endl;
			if(dis[v] > dis[u]+w){
				dis[v] = dis[u]+w;
				if(d[v] == d[u]&&!vis[v]){
					q.push({v,dis[v]}); 
				}
				
			}
		}
	}
	
} 
vector<int> b[30001];
void topu(int S){
	for(int i = 1;i <= tot;i++){
		if(in[i] == 0)t.push(i);
	}
	dis[S] = 0;
	pd[S] = 1;
	while(!t.empty()){
		int u = t.front();
		t.pop();
		//cout<<u<<endl;
		dijk(u);
		for(int v:b[u]){
			in[v]--;
			if(in[v] == 0){
				t.push(v);
			}
		}
	}
}
int main(){
	memset(dis,0x3f,sizeof(dis));
	cin>>n>>r>>p>>s;
	for(int i = 1;i <= r;i++){
		int u,v,w;
		cin>>u>>v>>w;
		g[u].push_back({v,w});
		g[v].push_back({u,w});
	}
	for(int i = 1;i <= n;i++){
		if(!d[i]){
			tot++;
			dfs(i,tot);
		}
	}
	for(int i = 1;i <= p;i++){
		int u,v,w;
		cin>>u>>v>>w;
		g[u].push_back({v,w});
		in[d[v]]++;
		pd[v] = 1;
		b[d[u]].push_back({d[v]});
	}
	topu(s);
	for(int i = 1;i <= n;i++){
		if(dis[i] > INF/2){
			cout<<"NO PATH"<<endl;
		}
		else{
			cout<<dis[i]<<endl;
		}
	}
} 
相关推荐
MZWeiei1 小时前
PTA:运用顺序表实现多项式相加
算法
GISer_Jing1 小时前
Javascript排序算法(冒泡排序、快速排序、选择排序、堆排序、插入排序、希尔排序)详解
javascript·算法·排序算法
cookies_s_s1 小时前
Linux--进程(进程虚拟地址空间、页表、进程控制、实现简易shell)
linux·运维·服务器·数据结构·c++·算法·哈希算法
不想编程小谭2 小时前
力扣LeetCode: 2506 统计相似字符串对的数目
c++·算法·leetcode
水蓝烟雨2 小时前
[HOT 100] 2187. 完成旅途的最少时间
算法·hot 100
菜鸟一枚在这3 小时前
深度解析建造者模式:复杂对象构建的优雅之道
java·开发语言·算法
gyeolhada3 小时前
2025蓝桥杯JAVA编程题练习Day5
java·数据结构·算法·蓝桥杯
阿巴~阿巴~3 小时前
多源 BFS 算法详解:从原理到实现,高效解决多源最短路问题
开发语言·数据结构·c++·算法·宽度优先
给bug两拳4 小时前
Day9 25/2/22 SAT
算法
_Itachi__4 小时前
LeetCode 热题 100 73. 矩阵置零
算法·leetcode·矩阵