• 【题解】2020-2021 SWERC I.Emails


    link

    题意

    给定(n)个人之间的关系图(无向图),一开始每个人的通讯录中有与他相邻的人的联系方式。在每一轮中,每个人都会将自己通讯录中所有人的联系方式发送给他当前通讯录中的所有人(注意不是一开始与他相邻的人)。求多少轮后所有都有所有其他人的联系方式。如果正确答案为(E),则你输出(E)(E+1)都视为正确。

    (2le nle 10^5,1le mle 10^5)

    题解

    易得在有限轮之后该过程一定停止,且两个人(u,v)(lceil log_2(d(u,v)) ceil)轮后相互知晓对方,故(E=lceil log_2(Diam (G)) ceil)。由于最后允许和答案有一轮的容忍程度,我们可以不需要精确求出图直径的长度。我们从任意一点出发(BFS),设与其最远的点和它的距离为(D),由于

    [Dle Diam(G)le 2D, ]

    [log_2 Dle log_2 Diam(G)le 1+log_2 D, ]

    所以

    [log_2 Diam(G)le log_2 D+1le log_2 Diam(G)+1, ]

    (Ele log_2 D+1le E+1),于是我们输出(lceil log_2 D ceil+1)即可。

    (Diam(G)le 2D)的证明

    反证法,假若不然,则有(Diam(G)>2D)。不妨设(s,t)是直径(Diam(G))的两端点,即(d(s,t)=Diam(G)),由于(d(u,s)le D,d(t,u)le D),所以(s ightarrow u ightarrow t)这条路径的长度不大于(2D),这与(d(s,t)=Diam(G)>2D)矛盾,故(Diam(G)le 2D)

    #include <bits/stdc++.h>
    #define cle(x) memset(x,0,sizeof(x))
    using namespace std;
    const int N=100005,M=200005;
    typedef long long ll;
    const ll INF=1ll<<55;
    struct edge{int v,w,nt;}e[M];
    int cnt=0,h[N];
    void add(int u,int v,int w){
    	e[++cnt].v=v;e[cnt].nt=h[u];e[cnt].w=w;h[u]=cnt;
    }
    int n,m,k,tag[N],S[N],p=0,a[N],b[N],cs=0,p1=0,p2=0,c[N],P,p3;
    ll ans,d[N];
    struct node{
    	int u;ll x;
    	bool operator<(const node &b)const{
    		return x>b.x;
    	}
    };
    priority_queue<node> q;
    int dij(int s){
    	while(!q.empty())q.pop();
    	for(int i=1;i<=n;i++)d[i]=INF;
    	d[s]=0;q.push(node{s,0});
    	while(!q.empty()){
    			node na=q.top();q.pop();
    			if(na.x!=d[na.u])continue;
    			for(int i=h[na.u];i;i=e[i].nt){
    				int v=e[i].v;
    				if(d[na.u]+e[i].w<d[v]){
    					d[v]=d[na.u]+e[i].w;
    					q.push((node){v,d[v]});
    				}
    			}
    		}
    		int res=0;
    	for(int i=1;i<=n;i++){
    		if(d[i]==INF){printf("-1");exit(0);}
    		res=max<int>(res,d[i]);
    	}
    	return res;
    }
    void f1(){
    	scanf("%d%d",&n,&m);
    	for(int i=1;i<=m;i++){
    		int x,y,z;scanf("%d%d",&x,&y);
    		add(x,y,1);add(y,x,1);
    	}
    	int res=dij(1);
    	int ans=(int)ceil(log2(res))+1;
    	printf("%d",ans);
    }
    int main(){
    	f1();
    	return 0;
    }
    
  • 相关阅读:
    Codeforces 514C Watto and Mechanism(字典树)
    计蒜客 直线的交点(计算几何 + 逆序对)
    Codeforces 837D Round Subset(背包)
    计蒜客 商汤科技的行人检测(随机化+计算几何)
    HDU 5893 List wants to travel(树链剖分+线段树)
    操作系统的中断处理
    Linux 安装 webmin
    Fedora 安装 phpMyAdmin(可能只有自己看得懂)
    httpd编译安装php
    IA-32e架构下的内核初始化内存管理
  • 原文地址:https://www.cnblogs.com/bobh/p/15375087.html
Copyright © 2020-2023  润新知