思路:应该是比较简单的一道题,因为点数是千数量级的,floyd肯定不行了,看到边数也是1000,这就暗示了要从边下手,直接bfs找每个S集合内的点到各点的最短路这就是O(n*m),S不连通则无满足点,否则寻找S集合内满足以下条件的点:
对于S中的点x,到达S中除x外任意点距离 <= t && 到达G-S集合点距离 > t 的点x
思路不难,但是也卡了不少时间,只因为最后用auto k : mp 寻找S内满足条件的点之前,所有点x都被mp[x]这样访问过了,因此实际上auto k:mp 等价于for( int i = 1 ; i <= n ; i++ );再加上没有用本地IDE,调试也废了不少时间,记录下以前没注意的
for( auto k : mp ){ //bfs时,所有点都被mp访问了,故auto遍历时都会访问
int i = k.first ;
int j ;
for( j = 1 ; j <= n ; j++ ){
if( i == j ) continue ;
if( mp[j] && ( dis[i][j] == -1 || dis[i][j] > t ) ) break ;
if( !mp[j] && dis[i][j] != -1 && dis[i][j] <= t ) break ;
}
if( j > n || ( i == n && j == n ) ) res.push_back(i) ;
}
#include <bits/stdc++.h>
#define INF 0x3f3f3f3f
using namespace std;
const int AX = 1e3 + 6 ;
int n , m ;
int k , t ;
vector<int>G[AX] ;
map<int,int>mp ;
vector<int>res ;
int dis[AX][AX] ;
struct Node{
int u , d ;
Node(){}
Node( int u , int d ):u(u),d(d){}
} ;
int vis[AX] ;
void bfs( int x ){
queue<Node>q ;
q.push( Node( x , 0 ) ) ;
vis[x] = 1 ;
while( !q.empty() ){
Node k = q.front() ; q.pop() ;
int u = k.u ;
int d = k.d ;
for( int i = 0 ; i < (int)G[u].size() ; i++ ){
int v = G[u][i] ;
if( !vis[v] ) { dis[x][v] = d + 1 ; q.push(Node(v,d+1)) ; vis[v] = 1 ;}
}
}
}
void solve(){
for( auto i : mp ){
memset( vis , 0 , sizeof(vis) ) ;
bfs( i.first ) ;
}
for( int i = 1 ; i <= n; i++ ){
if( !mp[i] ) continue ;
int j ;
for( j = 1 ; j <= n ; j++ ){
if( i == j ) continue ;
if( mp[j] && ( dis[i][j] == -1 || dis[i][j] > t ) ) break ;
if( !mp[j] && dis[i][j] != -1 && dis[i][j] <= t ) break ;
}
if( j > n || ( i == n && j == n ) ) res.push_back(i) ;
}
}
int main(){
int u , v ;
cin >> n >> m ;
memset( dis , -1 , sizeof(dis) ) ;
for( int i = 0 ; i < m ; i++ ){
cin >> u >> v ;
if( u == v ) continue ;
G[u].push_back(v) ;
G[v].push_back(u) ;
}
cin >> k >> t ;
for( int i = 0 ; i < k ; i++ ){
cin >> u ;
mp[u] = 1 ;
}
solve();
int len = res.size() ;
if( !len ) cout << "-1" << endl;
else{
for( int i = 0 ; i < len ; i ++ ){
cout << res[i] ;
if( i != len - 1 ) cout << ' ' ;
}
}
return 0 ;
}