/*
CodeForces - 796C
一个点的被干掉,影响他的两代及以内
分几种情况:1,如果只有一个最大(不妨叫他MAX)且别的(存在的)MAX-1都在他周围
则 是MAX
2.如果多个MAX环绕一个MAX
则是MAX+1(切断中间,然后返回到第一种情况。。)
3.其他呃呃,都是MAX+2了。
*/
#include<iostream>
#include<vector>
#define ll long long
using namespace std;
const int N=3e5+5;
struct node{//计数,计算某个点,他和他周围那些点的最大值,和最大值-1数目
int M1,M2;
};
node s[N];
vector<int> g[N];
int a[N];
int main()
{
int MAX=-2e9,n;
int max1=0,max2=0;
cin>>n;
for(int i=1;i<=n;i++)//计算最大值
{
scanf("%d",&a[i]);
MAX=max(a[i],MAX);
}
for(int i=1;i<n;i++)//邻接表
{
int u,v;
scanf("%d%d",&u,&v);
g[v].push_back(u);
g[u].push_back(v);
}
for(int i=1;i<=n;i++)
{
if(a[i]==MAX)max1++;
else if(a[i]==MAX-1)max2++;
}
for(int i=1;i<=n;i++)
{
for(int j=0;j<g[i].size();j++)
{
if(a[g[i][j]]==MAX)s[i].M1++;
else if(a[g[i][j]]==MAX-1)s[i].M2++;
}
if(a[i]==MAX)s[i].M1++;
else if(a[i]==MAX-1)s[i].M2++;
}
int i;
for(int i=1;i<=n;i++)
if(a[i]==MAX)break;
if(max1==1)
{
s[i].M2==max2;
cout<<MAX<<endl;
}
else{
for(int i=1;i<=n;i++)
{
if(s[i].M1==max1)
{
cout<<MAX+1<<endl;
return 0;
}
}
cout<<MAX+2<<endl;
return 0;
}
}
#include<iostream>
#include<cstdio>
#include<vector>
#include<queue>
#define ll long long
using namespace std;
typedef pair<int,int>ii;//第一个储存另一个点,第二个储存这是第几条边
const int N=3e5+7;
vector<ii>e[N];
queue<ii>q;
int ans,n,k,d;
int po[N];//警察局
bool vis[N];//是否访问过
bool mk[N];//mark
inline void bfs()
{
while(!q.empty())
{
ii now=q.front();
q.pop();
int u=now.first;
if(vis[u])continue;//如果访问过了
vis[u]=1;
for(int i=0;i<e[u].size();++i){
int v=e[u][i].first;
if(v!=now.second)
{
if(vis[v])
{
mk[e[u][i].second]=1;
ans++;
}
else q.push(ii(v,u));
}
}
}
}
int main()
{
cin>>n>>k>>d;
for(int i=1;i<=k;i++)
{
scanf("%d",&po[i]);
q.push(ii(po[i],0));
}
for(int i=1;i<=n-1;i++)
{
int u,v;
scanf("%d%d",&u,&v);
e[u].push_back(ii(v,i));
e[v].push_back(ii(u,i));
}
bfs();
cout<<ans<<endl;
for(int i=1;i<=n-1;i++)
{
if(mk[i])cout<<i<<' ';
}
cout<<endl;
}

被折叠的 条评论
为什么被折叠?



