12-9题目

/*
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;
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值