BZOJ P3732 Network

一开始想tarjan缩点之后再求倍增求lca的同时直接求最长边的最小值

然后发现还要预处理很多东西

1.强连通分量中的某两个点之间的贡献

2.从强连通分量中走出来连向另一个点的贡献

而我这种码农题就GG的人不就很萎吗?而且数据可能出成一整个强连通分量,直接GG

然后看了题解,说是最长边的最小值肯定在最小生成树上面

题解还说这一结论肥肠显然

然后我一脸懵逼,这怎么证明....

然后接下来我口胡一下

求MST的kruscal算法本身就是在避开最长边,往最短边走

...............口胡完毕

如果这还有疑问的话,我只能mmp了

下面是代码

并不能AC

#include<iostream>
#include<algorithm>
#include<cmath>
#include<cstring>
using namespace std;
struct bbbbb{
	int from,to,value;
}bian[300003];
bool cmp(bbbbb a,bbbbb b){
	return a.value<b.value;
}
int to[300003],nex[300003],head[300003],val[300003];
int fa[200003];
int depth[300003],in[300003],out[300003];
int chuo=0,n,m,k,tot,hehe;
int f[200003][25],maxlen[200003][25];
void add(int a,int b,int v){
	to[++tot]=b;
	nex[tot]=head[a];
	head[a]=tot;
	val[tot]=v;
}
int find(int x){
	if(fa[x]==x){
		return x;
	}else{
		return fa[x]=find(fa[x]);
	}
}
void kruscal(){
	sort(bian+1,bian+m+1,cmp);
	int now=0;
	for(int i=1;i<=n;i++){
		fa[i]=i;
	}
	for(int lei=1;lei<=n-1;now++){
		int faa=find(bian[now].from);
		int fab=find(bian[now].to);
		if(faa!=fab){
			fa[faa]=fab;
			add(bian[now].from,bian[now].to,bian[now].value);
			add(bian[now].to,bian[now].from,bian[now].value);
			hehe+=bian[now].value;
			lei++;
		}
	}
}
int dfs(int fa,int now){
	in[now]=++chuo;
	f[now][0]=fa;
	for(int i=head[now];i;i=nex[i]){
		if(to[i]!=fa){
			dfs(now,to[i]);
			maxlen[to[i]][0]=val[i];
		}
	}
	out[now]=++chuo;
}
bool pd(int x,int y){
	if(in[x]<=in[y]&&out[x]>=out[y]){
		return true;
	}
	return false;
}
int lca(int x,int y){
	if(pd(x,y))return x;
	if(pd(y,x))return y;
	int k=x;
	for(int i=20;i>=0;i--){
		if(!pd(f[k][i],y)){
			k=f[k][i];
		}
	}
	return f[k][0];
}
int ju(int a,int b){
	int k=b;
	int ans=0;
	for(int i=20;i>=0;i--){
		if(!pd(f[k][i],a)&&k!=1){
			k=f[k][i];
			ans=max(ans,maxlen[k][i]);
		}
	}
	return ans;
}
int main(){
	cin>>n>>m>>k;
	for(int i=1;i<=m;i++){
		int a,b,v;
		cin>>bian[i].from>>bian[i].to>>bian[i].value;
	}
	kruscal();
	cout<<hehe<<endl;
	dfs(0,1);
	for(int i=1;i<=n;i++){
		for(int j=1;j<=20;j++){
			f[i][j]=f[f[i][j-1]][j-1];
			maxlen[i][j]=max(maxlen[maxlen[i][j-1]][j-1],maxlen[i][j-1]);
		}
	}
	for(int i=1;i<=n;i++){
		cout<<f[i][1]<<endl;
	}
	for(int i=1;i<=k;i++){
		int a,b;
		cin>>a>>b;
		int lcalca=lca(a,b);
		cout<<"the_lca:"<<lcalca<<endl;
		cout<<max(ju(lcalca,a),ju(lcalca,b))<<endl;
	}
	return 0;
}
/*
in:
6 6 9
1 2 5
2 3 4
3 4 3
1 4 8
2 5 7
4 6 2
1 2
1 3
1 4
2 3
2 4
5 1
6 2
6 1
3 5

out:
5
5
5
4
4
7
4
5
*/


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
YOLO高分设计资源源码,详情请查看资源内容中使用说明 YOLO高分设计资源源码,详情请查看资源内容中使用说明 YOLO高分设计资源源码,详情请查看资源内容中使用说明 YOLO高分设计资源源码,详情请查看资源内容中使用说明YOLO高分设计资源源码,详情请查看资源内容中使用说明YOLO高分设计资源源码,详情请查看资源内容中使用说明YOLO高分设计资源源码,详情请查看资源内容中使用说明YOLO高分设计资源源码,详情请查看资源内容中使用说明YOLO高分设计资源源码,详情请查看资源内容中使用说明YOLO高分设计资源源码,详情请查看资源内容中使用说明YOLO高分设计资源源码,详情请查看资源内容中使用说明YOLO高分设计资源源码,详情请查看资源内容中使用说明YOLO高分设计资源源码,详情请查看资源内容中使用说明YOLO高分设计资源源码,详情请查看资源内容中使用说明YOLO高分设计资源源码,详情请查看资源内容中使用说明YOLO高分设计资源源码,详情请查看资源内容中使用说明YOLO高分设计资源源码,详情请查看资源内容中使用说明YOLO高分设计资源源码,详情请查看资源内容中使用说明YOLO高分设计资源源码,详情请查看资源内容中使用说明YOLO高分设计资源源码,详情请查看资源内容中使用说明YOLO高分设计资源源码,详情请查看资源内容中使用说明YOLO高分设计资源源码,详情请查看资源内容中使用说明YOLO高分设计资源源码,详情请查看资源内容中使用说明YOLO高分设计资源源码,详情请查看资源内容中使用说明YOLO高分设计资源源码,详情请查看资源内容中使用说明YOLO高分设计资源源码,详情请查看资源内容中使用说明

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值