1. 程式人生 > >cf796d 樹,bfs好題!

cf796d 樹,bfs好題!

絕對是好題,把所有警察局放入佇列然後開始廣搜,如果碰到了vis過的頂點,但是那條邊沒有訪問過,那麼這條邊就可以刪掉

另外廣搜的vis標記是在入隊時就打的,,

#include<bits/stdc++.h>
using namespace std;
#define maxn 300005

struct Edge{
    int to,next,flag,id;
}edge[maxn<<1];
int n,k,d,head[maxn],tot,p[maxn],vis[maxn];

void init(){
    tot=0;
    memset(vis,0,sizeof
vis); memset(head,-1,sizeof head); } void addedge(int u,int v,int id){ edge[tot].to=v;edge[tot].flag=0;edge[tot].id=id;edge[tot].next=head[u]; head[u]=tot++; } int main(){ int u,v; init(); scanf("%d%d%d",&n,&k,&d); for(int i=1;i<=k;i++)scanf("%d",&p[i]);
for(int i=1;i<n;i++){ scanf("%d%d",&u,&v); addedge(u,v,i);addedge(v,u,i); } queue<int> q;while(!q.empty())q.pop(); for(int i=1;i<=k;i++)q.push(p[i]),vis[p[i]]=1; while(!q.empty()){ int u=q.front();q.pop(); //cout << u << '\n';
for(int i=head[u];i!=-1;i=edge[i].next){ int v=edge[i].to; //cout << v << ' '; if(vis[v] && !edge[i].flag){ edge[i].flag=edge[i^1].flag=2; continue; } else if(!vis[v] && !edge[i].flag){ edge[i].flag=edge[i^1].flag=1; vis[v]=1; q.push(v); } } } int ans=0; for(int i=0;i<tot;i+=2) if(edge[i].flag==2) ans++;printf("%d\n",ans); for(int i=0;i<tot;i+=2) if(edge[i].flag==2) printf("%d ",edge[i].id); return 0; }