专栏文章

题解:CF1486E Paired Payment

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

文章操作

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

当前评论
0 条
当前快照
1 份
快照标识符
@miqe7ggz
此快照首次捕获于
2025/12/04 03:21
3 个月前
此快照最后确认于
2025/12/04 03:21
3 个月前
查看原文
算多维最短路的模板了吧。
类似于 dp,维护三个状态:
  • uu:遍历到了那个点。
  • scsc:对于第奇数条边(奇数特指已选了奇数条边),该边权值。
  • nownow:当前是第奇/偶次选择。
以下设 distdist 为最短路数组,wa,bw_{a,b}aba \to b 的边权。
转移:
distj,wu,j,1=minujdistu,0,0dist_{j,w_{u,j},1}=\min_{u \to j}{dist_{u,0,0}} distj,0,0=minujdistu,sc,1+(sc+wu,j)2dist_{j,0,0}=\min_{u \to j} dist_{u,sc,1} + (sc+w_{u,j})^2
最后输出即可。

代码

CPP
#include<iostream>
#include<queue>
#include<cstring>
using namespace std;
int n,m;
const int N=1e5+10;
int h[N<<2],w[N<<2],e[N<<2],ne[N<<2],idx;
inline void add(int a,int b,int c){
	e[idx]=b,w[idx]=c,ne[idx]=h[a],h[a]=idx++;
}
long long dist[N][110][2];
bool st[N][110][2];
struct node{
	int u;
	long long sc,dis;
	bool now;
	bool operator<(const node &t)const{
		return dis>t.dis;
	}
};
void dj(){
	priority_queue<node> q;
	q.push({1,0,0,0});
	memset(dist,0x3f,sizeof dist);
	memset(st,0,sizeof st);
	dist[1][0][0]=0;
	while(q.size()){
		node t=q.top();
		q.pop();
		int u=t.u;
		long long sc=t.sc;
		bool now=t.now;
		if(st[u][sc][now]){
			continue;
		}
		st[u][sc][now]=1;
//		cout<<u<<' '<<sc<<' '<<now<<' '<<dist[u][sc][now]<<endl;
		for(int i=h[u];~i;i=ne[i]){
			int j=e[i];
			if(now==0){
				if(dist[j][w[i]][1]>dist[u][0][0]){
					dist[j][w[i]][1]=dist[u][0][0];
					q.push({j,w[i],dist[j][w[i]][1],1});
				}
			}else{
				if(dist[j][0][0]>dist[u][sc][1]+(sc+w[i])*(sc+w[i])){
					dist[j][0][0]=dist[u][sc][1]+(sc+w[i])*(sc+w[i]);
					q.push({j,0,dist[j][0][0],0});
				}
			}
		}
	}
}
long long ans[N];
int main(){
	memset(h,-1,sizeof h);
	cin>>n>>m;
	while(m--){
		int a,b,c;
		scanf("%d%d%d",&a,&b,&c);
		add(a,b,c);
		add(b,a,c);
	}
	dj();
	for(int i=1;i<=n;i++){
		if(dist[i][0][0]>=1e18){
			dist[i][0][0]=-1;
		}
		printf("%lld ",dist[i][0][0]);
	}
	return 0;
}

评论

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

正在加载评论...