CF #328div2 D

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

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

可以知道,被攻击的城市必定可以组成一棵树,然后,传送到的点必定也是城市之一。如果出发后回到原点,则需要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;
}

  

时间: 2024-12-24 15:34:23

CF #328div2 D的相关文章

微信 {&quot;errcode&quot;:40029,&quot;errmsg&quot;:&quot;invalid code, hints: [ req_id: Cf.y.a0389s108 ]&quot;}

{"errcode":40029,"errmsg":"invalid code, hints: [ req_id: Cf.y.a0389s108 ]"} 问题:微信网页授权后,获取到 openid 了,一刷新又没了 微信网页授权获取到的 code 只能使用一次(5分钟内有效),使用一次后,马上失效. 页面授权跳转成功,根据 code 也换取到 openid 了. 此时刷新页面,并不会再次进行授权,而是直接刷新了一下上一次授权跳转后的链接,带的还是

CF with friends and user&#39;s influence considered on NYC data(updated Aug,11st)

Here is the code link: https://github.com/FassyGit/LightFM_liu/blob/master/U_F1.py I use NYC data as other experimens. The split of the training data was seperated by the timeline, and I have normalised the interaction matrix by replacing the checkin

CF 750

今天CF打的块残废了     就是一废物 A 在24点之前到 直接模拟即可 #include<stdio.h> #include<algorithm> #include<cstring> #include<string> #include<cmath> using namespace std; #define LL long long #define MAXN 1010 #define inf 1000000000.0 int main() {

CF #394 (2) 5/6

Codeforces Round #394 (Div. 2) 总结:有毒的一场比赛.做了三题,结果A被叉,B.C挂综测,还hack失败一发,第一次在CF体会到了-50分的感觉..不知道是不是人品好,比赛时room炸了,然后,unrated.. A  水题,判一下0 0,然后abs(a-b)<=1 B  水题,组个间距比较一下,但一个数的时候要判一下 C  直接暴力上的题 D  也是xjb暴力 题意:给出n,l,r, a[], p[],另有两个数组b[], c[],ci=bi-ai.l<=ai,

一场CF的台前幕后(上)——转

前奏 大约4月份的时候,业界毒瘤pyx噔噔噔跑过来说:“酷爱!我YY了一道题!准备当CF的C” 我当时就被吓傻了."Yet another Chinese round?" “区间取模,区间求和” 感觉这题还不错?不过pyx嫌水了…… 好办!当时我刚刚出完动态仙人掌不久,于是一拍脑袋说:把这个问题出到仙人掌上去! 当然被pyx鄙视了…… 后来一直就没啥动静,直到5月底的CTSC. 试机的时候pyx给我看了套他出的神题……里面有一道题……我不小心读成了下面这个样子: “给定n个m维的模2意

[2016-03-22][CF][69A][Young Physicist]

时间:2016-03-22 19:41:34 星期二 题目编号:[2016-03-22][CF][69A][Young Physicist] 题目大意:判断向量和是否为0 分析:对应坐标相加 遇到的问题:不能用x+y+z来判断是否都为0,除非输入都是正数 #include <cstdio> using namespace std; int main(){ int a,b,c,x,y,z,n; x = y = z = 0; scanf("%d",&n); for(in

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

在开发iOS应用程序时我们有时会用到Core Foundation对象简称CF,例如Core Graphics.Core Text,并且我们可能需要将CF对象和OC对象进行互相转化,我们知道,ARC环境下编译器不会自动管理CF对象的内存,所以当我们创建了一个CF对象以后就需要我们使用CFRelease将其手动释放,那么CF和OC相互转化的时候该如何管理内存呢?答案就是我们在需要时可以使用__bridge,__bridge_transfer,__bridge_retained,具体介绍和用法如下

【CF 520D】Cubes

[CF 520D]Cubes 怎么说呢--英语阅读题+超级大模拟-- 最重要的是知道怎么出来的数据...题意好懂 xy坐标内给出几个单位正方形 以正方形左下点坐标给出 y=0为地面 正方形下面或者左右下方至少存在一个正方形他才能稳定.. 正方形按0~m-1标号 每次只能取出不影响整体结构的正方形 甲乙玩一个游戏 交替取正方形 每取下一个按从左到右的顺序排好 得到一个大数 重点来了! 取出的数是m进制 转换为十进制是最终结果 甲希望结果最大 乙希望结果最小 问结果为多少 甲先取 题意明白了模拟就行

cf 148D Bag of mice

The dragon 选一只老鼠,然后会跑掉一只 the princess选一只老鼠,不会跑出另外的老鼠 求the princess赢的概率 1 #include<iostream> 2 #include<string> 3 #include<cstdio> 4 #include<vector> 5 #include<queue> 6 #include<stack> 7 #include<algorithm> 8 #inc