这题不难,当时想出来了,可是却写不出来~~

现在慢慢写回来,也写得好挫~

可以知道,被攻击的城市必定可以组成一棵树,然后,传送到的点必定也是城市之一。如果出发后回到原点,则需要2E,E是树的边数,则2E-D就是答案,D是树中直径。

我写得好锉~

#include <iostream>
#include <cstdio>
#include <algorithm>
#include <cstring>
#include <queue>
#define LL long long
using namespace std; const int MAX=123460; struct Edge{
int u,v,next;
}edge[MAX*2]; int head[MAX],dis[MAX];
int n,m,tot;
bool chose[MAX];
int pre[MAX],point[MAX],deg[MAX];
int dis1[MAX],node1[MAX],dis2[MAX],node2[MAX];
bool vis[MAX]; void addedge(int u,int v){
edge[tot].u=u;
edge[tot].v=v;
edge[tot].next=head[u];
head[u]=tot++;
} int BFS(int rt,int counts){
queue<int>que;
que.push(rt);
vis[rt]=true;
int u,v;
while(!que.empty()&&counts){
u=que.front();
que.pop();
vis[u]=true;
if(chose[u]) counts--;
for(int e=head[u];e!=-1;e=edge[e].next){
v=edge[e].v;
if(vis[v]) continue;
que.push(v);
pre[v]=u;
}
}
memset(vis,false,sizeof(vis));
while(!que.empty()) que.pop(); for(int i=1;i<=m;i++) que.push(point[i]);
while(!que.empty()){
u=que.front();
que.pop();
v=pre[u];
if(v!=-1){
if(!vis[v]){
que.push(v);
chose[v]=false;
}
vis[v]=true;
}
} while(!que.empty()) que.pop();
memset(vis,false,sizeof(vis));
for(int i=1;i<=m;i++) if(chose[point[i]]) que.push(point[i]);
memset(deg,0,sizeof(deg));
int ans=0;
while(!que.empty()){
u=que.front();
vis[u]=true;
que.pop();
v=pre[u];
if(v!=-1){
ans++;
if(!vis[v])
que.push(v);
deg[v]++;
vis[v]=true;
}
} while(!que.empty()) que.pop();
for(int i=1;i<=m;i++) if(chose[point[i]]) que.push(point[i]);
while(!que.empty()){
u=que.front();
dis[dis1[u]]=dis[dis1[u]]==0?min(node1[u],u):min(min(node1[u],u),dis[dis1[u]]);
dis[dis1[u]+dis2[u]]=dis[dis1[u]+dis2[u]]==0?min(node1[u],node2[u]):min(min(node1[u],node2[u]),dis[dis1[u]+dis2[u]]);
que.pop();
v=pre[u];
if(v!=-1){
deg[v]--;
if(!deg[v]) que.push(v);
dis1[u]+=1;
if(dis1[u]>dis1[v]){
dis2[v]=dis1[v],node2[v]=node1[v];
dis1[v]=dis1[u],node1[v]=node1[u];
}
else if(dis1[u]==dis1[v]){
if(node1[u]<node1[v]){
dis2[v]=dis1[v],node2[v]=node1[v];
node1[v]=node1[u];
}
else{
if(dis1[u]>dis2[v]){
dis2[v]=dis1[u],node2[v]=node1[u];
}
else if(dis1[u]==dis2[v]){
if(node1[u]<node2[v]){
node2[v]=node1[u];
}
}
}
}
else{
if(dis1[u]>dis2[v]){
dis2[v]=dis1[u],node2[v]=node1[u];
}
else if(dis1[u]==dis2[v]){
if(node1[u]<node2[v]){
node2[v]=node1[u];
}
}
} }
}
/// cout<<ans<<endl;
/// printf("%d\n",node1[rt]);
for(int i=n;i>=1;i--){
if(dis[i]>0){
printf("%d\n",dis[i]);
return ans*2-i;
}
}
printf("%d\n",point[1]);
return ans; } int main(){
int u,v;
while(scanf("%d%d",&n,&m)!=EOF){
for(int i=1;i<=n;i++){
head[i]=-1,chose[i]=false,pre[i]=-1;
dis1[i]=dis2[i]=0,node1[i]=node2[i]=i;
vis[i]=false; dis[i]=0;
}
tot=0;
for(int i=1;i<n;i++){
scanf("%d%d",&u,&v);
addedge(u,v);
addedge(v,u);
}
for(int i=1;i<=m;i++){
scanf("%d",&u);
point[i]=u;
chose[u]=true;
}
printf("%d\n",BFS(u,m)); }
return 0;
}

  

CF #328div2 D的更多相关文章

  1. ORA-00494: enqueue [CF] held for too long (more than 900 seconds) by 'inst 1, osid 5166'

    凌晨收到同事电话,反馈应用程序访问Oracle数据库时报错,当时现场现象确认: 1. 应用程序访问不了数据库,使用SQL Developer测试发现访问不了数据库.报ORA-12570 TNS:pac ...

  2. cf之路,1,Codeforces Round #345 (Div. 2)

     cf之路,1,Codeforces Round #345 (Div. 2) ps:昨天第一次参加cf比赛,比赛之前为了熟悉下cf比赛题目的难度.所以做了round#345连试试水的深浅.....   ...

  3. cf Round 613

    A.Peter and Snow Blower(计算几何) 给定一个点和一个多边形,求出这个多边形绕这个点旋转一圈后形成的面积.保证这个点不在多边形内. 画个图能明白 这个图形是一个圆环,那么就是这个 ...

  4. ARC下OC对象和CF对象之间的桥接(bridge)

    在开发iOS应用程序时我们有时会用到Core Foundation对象简称CF,例如Core Graphics.Core Text,并且我们可能需要将CF对象和OC对象进行互相转化,我们知道,ARC环 ...

  5. [Recommendation System] 推荐系统之协同过滤(CF)算法详解和实现

    1 集体智慧和协同过滤 1.1 什么是集体智慧(社会计算)? 集体智慧 (Collective Intelligence) 并不是 Web2.0 时代特有的,只是在 Web2.0 时代,大家在 Web ...

  6. CF memsql Start[c]UP 2.0 A

    CF memsql Start[c]UP 2.0 A A. Golden System time limit per test 1 second memory limit per test 256 m ...

  7. CF memsql Start[c]UP 2.0 B

    CF memsql Start[c]UP 2.0 B B. Distributed Join time limit per test 1 second memory limit per test 25 ...

  8. CF #376 (Div. 2) C. dfs

    1.CF #376 (Div. 2)    C. Socks       dfs 2.题意:给袜子上色,使n天左右脚袜子都同样颜色. 3.总结:一开始用链表存图,一直TLE test 6 (1)如果需 ...

  9. CF #375 (Div. 2) D. bfs

    1.CF #375 (Div. 2)  D. Lakes in Berland 2.总结:麻烦的bfs,但其实很水.. 3.题意:n*m的陆地与水泽,水泽在边界表示连通海洋.最后要剩k个湖,总要填掉多 ...

随机推荐

  1. Linux下sublime 无法输入中文的解决

    个人认为linux下的编辑器,对于小白来说,最好用的就是sublime了,但是,安装之后敲代码无法输入中文 ,很尴尬. 百度后,发现了解决方法. 项目链接:https://github.com/lyf ...

  2. RT-Thread 设备驱动I2C浅析及使用

    由于 I2C 可以控制多从机的属性,设备驱动模型分为  I2C总线设备(类似与Linux里面的I2C适配器) + I2C从设备: 系统I2C设备驱动主要实现 I2C 总线设备驱动,而具体的I2C 从设 ...

  3. centos源更新

    .备份 mv /etc/yum.repos.d/CentOS-Base.repo /etc/yum.repos.d/CentOS-Base.repo.backup .下载新的CentOS-Base.r ...

  4. call( )、apply( )

    call( )和apply( )都是用于改变函数执行时的上下文,唯一最大区别在于传入参数的形式不同. 这两个函数都是函数的方法,只有函数能够打点调用call().apply(),表示用指定的上下文执行 ...

  5. JVM 内存区域划分

    一.运行时数据区包括哪几部分? 根据<Java虚拟机规范>的规定,运行时数据区通常包括这几个部分:程序计数器(Program Counter Register).Java栈(VM Stac ...

  6. 【译】x86程序员手册14-5.1段转换

    5.1 Segment Translation 段转换 Figure 5-2 shows in more detail how the processor converts a logical add ...

  7. eclipse中代码整体左右移动的方法

    1.向左:将要移动的代码选中,然后按TAB键2.向右:将要移动的代码选中,然后按shift+tab键 kettas:  2009-8-21

  8. python socket 接口

    一.简介 socket通常也称作"套接字",用于描述IP地址和端口,是一个通信链的句柄,应用程序通常通过"套接字"向网络发出请求或者应答网络请求.socket起 ...

  9. Python 内置函数 day4

    import random s = 'abczfg' st= {3,4,9,1,8} print(dir(random))#打印模块内的方法,输出模块/变量可以调用的方法 print(dir(s))# ...

  10. C++编写谷歌日历

    #include<iostream> #include<fstream> using namespace std; void main() //程序从这里开始运行 { int ...