20分求查错(带注释)
  • 板块P1395 会议
  • 楼主取啥名好
  • 当前回复5
  • 已保存回复5
  • 发布时间2020/9/8 13:31
  • 上次更新2023/11/5 13:33:31
查看原帖
20分求查错(带注释)
173397
取啥名好楼主2020/9/8 13:31

本题跟https://www.luogu.com.cn/problem/P3478 类似,上面那道我A了,魔改了代码提交到这题就只剩20分,两题的思路都是一模一样的

#include<bits/stdc++.h>
using namespace std;
int n,k,a,b,jl,cnt=0,num=0,link[110000]={0},mark[110000]={0},head[310000]={0};
struct node{int to,next;}tree[210000];
queue<int> q,qt,qk;
void add(int u,int v){
    cnt++;tree[cnt].to=v;tree[cnt].next=head[u];head[u]=cnt;
    cnt++;tree[cnt].to=u;tree[cnt].next=head[v];head[v]=cnt;
}
void dfs(int x,int fa,int dis){
    jl+=dis;
    for(int i=head[x];i;i=tree[i].next){
        if(tree[i].to==fa)continue;
        dfs(tree[i].to,x,dis+1);
    }//在找到开会地点后计算路径和,累计每个点到开会地点的距离
}
int main(){
    cin>>n;
    for(int i=1;i<n;i++){cin>>a>>b;add(a,b);link[a]++,link[b]++;}num=n;//link指与该点直接连接的点数
    for(int i=1;i<=n;i++){if(link[i]==1)q.push(i),num--,mark[i]=1;}//找到所有的叶子结点
    while(num>2){
        while(!q.empty()){int temp=q.front();q.pop();
            for(int i=head[temp];i;i=tree[i].next){link[tree[i].to]--;//在删掉一个叶节点后删掉与其相邻的点的连接数
                if(link[tree[i].to]==1){qt.push(tree[i].to);num--;mark[tree[i].to]=1;}//如果成为叶节点就加入队列,等下一轮删掉
            }
        }q=qt;qt=qk;//qk是空队列,这样直接清空qt
    }//一圈一圈的删点,删到只剩两个或一个,开会地点就在这里面。
    for(int i=1;i<=n;i++)if(!mark[i]){cout<<i<<" ";dfs(i,0,0);break;}//找小的点
    cout<<jl;
    system("pause");return 0;
}
2020/9/8 13:31
加载中...