专栏文章

题解:P14618 [2019 KAIST RUN Fall] Lexicographically Minimum Walk

P14618题解参与者 1已保存评论 0

文章操作

快速查看文章及其快照的属性,并进行相关操作。

当前评论
0 条
当前快照
1 份
快照标识符
@mimz9neg
此快照首次捕获于
2025/12/01 17:59
3 个月前
此快照最后确认于
2025/12/01 17:59
3 个月前
查看原文

Solution

接触过一个加强版,区别在于本题保证边权两两不同。
首先字典序最小肯定是满足贪心的,每一步尽可能往小走。
其次你要保证你走的地方最终存在一条路径到达 TT 点。
所以先建反图把所有 TT 点能够到达的地方跑出来,然后再去原图上做贪心。
如果 TT 无法到达 SS 就是 IMPOSSIBLE,如果贪心的时候走到了之前走过的点就是 TOO LONG

Code

CPP
#include<bits/stdc++.h>
#define int long long
#define INF 1e18
#define N 1000005
using namespace std;
struct star{
	int next,to,v1,v2;
}e[N];
int n,m,s,t,head[N],cnt,vis[N],vv[N],a[N],tot;
void add(int u,int v,int w1,int w2){
	e[++cnt].next=head[u];
	head[u]=cnt,e[cnt].to=v;
	e[cnt].v1=w1,e[cnt].v2=w2;
}
void dfs(int x){
	vis[x]=1;
	for(int i=head[x];i;i=e[i].next){
		int y=e[i].to,d=e[i].v2;
		if(!d||vis[y]) continue;
		dfs(y);
	}
}
void dfs1(int x){
	if(x==t){
		for(int i=1;i<=tot;i++) cout<<a[i]<<" ";
		exit(0);
	}
	if(vv[x]){
		cout<<"TOO LONG"; exit(0);
	}
	vv[x]=1; int qwq=INF,id;
	for(int i=head[x];i;i=e[i].next){
		int y=e[i].to,d1=e[i].v1,d2=e[i].v2;
		if(d2||!vis[y]) continue;
		if(d1<qwq) qwq=d1,id=y;
	}
	a[++tot]=qwq,dfs1(id);
}
signed main(){
	ios::sync_with_stdio(false);
	cin>>n>>m>>s>>t;
	for(int i=1,u,v,w;i<=m;i++)
		cin>>u>>v>>w,add(u,v,w,0),add(v,u,w,1);
	dfs(t);
	if(!vis[s]){
		cout<<"IMPOSSIBLE";
		return 0;
	}
	dfs1(s);
	return 0;
}

评论

0 条评论,欢迎与作者交流。

正在加载评论...