(CodeForces) D. Police Stations
阿新 • • 發佈:2018-12-11
題目大意:一個連通圖(樹型),每個點都是一個城市,有些城市是有警察局的,任何城市都可以到達d距離的警察局,即每個警察局都有一個有效範圍d.問你最多可以刪除多少條路,使得每個城市依然可以到達警察局。
解題思路:我們可以這樣想,既然給了你k個警察局,那當然是每個都要用上才是最優的,每個城市都應該優先選擇和它最近的警察局,如果它選擇遠的,只會多走一些沒有必要的路徑。所以可以從每個警察局同時開始寬搜,同時標記走過的邊,如果圖上所有的城市都被標記,那就寬搜結束。
#include<bits/stdc++.h> using namespace std; typedef long long ll; const ll maxn=3e5+5; int n,k,d,cnt=0; bool vis[maxn]; bool edgevis[maxn]; vector<int> added; struct edge { int to; int id; }; vector<edge> ee[maxn]; struct node { int p; int step; }; queue<node> q; void bfs(){ while(!q.empty()){ node st=q.front(); int np=st.p,nstep=st.step; q.pop(); if(nstep>d) continue; for(int i=0;i<(int)ee[np].size();++i){ edge tt=ee[np][i]; int nto=tt.to,nid=tt.id; if(!vis[nto]){ vis[nto]=true; edgevis[nid]=true; ++cnt; q.push(node{nto,nstep+1}); } } } } int main() { scanf("%d%d%d",&n,&k,&d); memset(vis,false,sizeof(vis)); memset(edgevis,false,sizeof(edgevis)); int tmp; for(int i=1; i<=k; ++i) { scanf("%d",&tmp); q.push(node{tmp,0}); vis[tmp]=true; } int x,y; for(int i=1; i<=n-1; ++i) { scanf("%d%d",&x,&y); ee[x].push_back(edge {y,i}); ee[y].push_back(edge {x,i}); } bfs(); cout<<n-1-cnt<<endl; for(int i=1; i<=n-1; ++i) { if(edgevis[i]==false) { cout<<i<<' '; } } cout<<endl; return 0; }