社区讨论

求卡常。(时间复杂度好像对的?)

P3304[SDOI2013] 直径参与者 2已保存回复 6

讨论操作

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

当前回复
5 条
当前快照
1 份
快照标识符
@mkfcsfmt
此快照首次捕获于
2026/01/15 19:15
上个月
此快照最后确认于
2026/01/18 12:05
上个月
查看原帖
时间复杂度 O(n)O(n)
关于那个 dfs2\bm{dfs2},加了 vis 标记。
所以 nn 遍应该是 O(n)O(n) 吧。
CPP
#include<bits/stdc++.h>
using namespace std;
#define int long long
#define endl '\n'
const int N=200000+20;
struct edge{
	int nxt,to,w;
}ed[N<<1];
int head[N],tot=0,n,dist[N],root=0;
bitset<N> vis;
void add(int a,int b,int w){
	ed[++tot].to=b;
	ed[tot].nxt=head[a];
	ed[tot].w=w;
	head[a]=tot;
}
int strat,End,fa[N], maxd=-1;
void dfs(int id,int father,int d){
	fa[id]=father;
	dist[id]=dist[father]+d;
	for(int i=head[id];i;i=ed[i].nxt){
		int t=ed[i].to;
		if(t!=father) {
			dfs(t,id,ed[i].w);
		}
	}
}
int dfs2(int id,int f){
	int ans=0;
	for(int i=head[id];i;i=ed[i].nxt){
		int t=ed[i].to;
		if(t!=f&&!vis[t]){
			ans=max(ans,dfs2(t,id)+ed[i].w);
		}
	}
	return ans;
}
namespace IO{
    #ifdef ONLINE_JUDGE
    #define getchar getchar_unlocked
    #define putchar putchar_unlocked
    #endif
    inline int read(){
	    int x=0;char ch=getchar();
	    while(ch<'0'||ch>'9'){ch=getchar();}
	    while(ch>='0'&&ch<='9'){x=(x << 1) + (x << 3)+ch-48;ch=getchar();}
	    return x;
    }
    inline void write(int x) {
	    static int sta[35];
	    int top =0;
	    do{sta[top++]=x%10,x/=10;}while (x);
	    while(top) putchar(sta[--top]+48);
    }
}
using namespace IO;
signed main(){
	ios::sync_with_stdio(false);
	cin.tie(0);
	cout.tie(0);
	n=read();
	for(int i=1;i<n;++i){
		int id,v,W;
		id=read(),v=read(),W=read();
		add(id,v,W);
		add(v,id,W);
	}
	dfs(1,0,0);
	for(int i=1;i<=n;++i){
		if(maxd<dist[i]){
			maxd=dist[i];
			root=i;
		}
	}
	dfs(root,0,0);
	for(int i=1;i<=n;++i){
		if(maxd<dist[i]){
			maxd=dist[i];
			End=i;
		}
	}
	write(dist[End]);putchar('\n');
	for(int i=fa[End];i!=0;i=fa[i]){
		vis[i]=1;
	}
	int l,r;
	l=root,r=End;
	for(int i=fa[End];i!=root;i=fa[i]){
		int d=dfs2(i,0);
		if(d==dist[End]-dist[i])r=i;
		if(d==dist[i]&&l==root)l=i;
	}
	int ans;
	if(l==r)write(0);
	else{
		ans=1;
		for(int i=fa[r];i!=l;i=fa[i]){
			ans++;
		}
		write(ans);
	}
	//cout<<l<<" "<<r<<" "<<End<<endl;
}

回复

6 条回复,欢迎继续交流。

正在加载回复...