题目描述
Once again you lost days refactoring code, which never runs in the first place. Enough is enough – your time is better spent writing a tool that finds unused code!
Your software is divided into packages and executables. A package is a collection of meth- ods. Executables are packages defining among other methods exactly one method with name PROGRAM. This method is executed on the start of the corresponding executable. Ordinary packages have no method named PROGRAM.
Each method is uniquely identified by the combination of package and method names. E.g. the method with the identifier SuperGame::PROGRAM would be the main method of the executable SuperGame.
For every method in your software you are given a list of methods directly invoking it. Thus you can easily identify methods, that are never called from any method. However, your task is more challenging: you have to find unused methods. These are methods that are never reached by the control flow of any executable in your software.
数据范围
N<=400N<=400
分析
看着题目觉得很难,可能是一道神仙题,但是打完回去再看的时候发现其实很简单,对每个PROGAM直接hash一下,化成一道图论暴力就可以了,剩下的就是多源的一个类floodfill的东西,怕炸栈所以写了bfs。
#include <bits/stdc++.h>
#define rep( i , l , r ) for( int i = (l) ; i <= (r) ; ++i )
#define per( i , r , l ) for( int i = (r) ; i >= (l) ; --i )
#define erep( i , u ) for( int i = head[(u)] ; ~i ; i = e[i].nxt )
using namespace std;
int _read(){
char ch = getchar();
int x = 0 , f = 1 ;
while( !isdigit( ch ) )
if( ch == '-' ) f = -1 , ch = getchar();
else ch = getchar();
while( isdigit( ch ) )
x = (ch - '0') + x * 10 , ch = getchar();
return x * f;
}
const int maxn = 400 + 5 , maxm = 300000 + 5;
struct edge{
int v , nxt;
} e[maxm];
int head[maxn] , _t = 0;
inline void addedge( int u , int v ){
e[_t].v = v , e[_t].nxt = head[u] , head[u] = _t++;
}
const char S[10] = "::PROGRAM";
inline bool ck( string s ){
if( s.length() <= 9 ) return 0;
int l = s.length();
rep( j , 0 , 8 )
if( S[j] != s[l + j - 9] ) return 0;
return 1;
}
map<string,int> h;
int f[maxn] , N , tot = 0;
void prework(){
scanf("%d" , &N);
rep( i , 1 , N ){
string s; int K = 0;
cin >> s >> K;
if( h.count(s) == 0 ){
h[s] = ++tot;
f[tot] = ck( s );
}
rep( j , 1 , K ){
string ss;
cin >> ss;
if( h.count(ss) == 0 ){
h[ss] = ++tot;
f[tot] = ck( ss );
}
addedge( h[ss] , h[s] );
}
}
}
#define FR front()
int dis[maxn];
void bfs(){
queue<int> q;
memset( dis , 0xff , sizeof dis );
rep( i , 1 , tot )
if( f[i] == 1 ){
q.push( i ) ; dis[i] = 0;
}
while( !q.empty() ){
int u = q.FR; q.pop();
erep( i , u ){
int v = e[i].v;
if( dis[v] == -1 ){
dis[v] = dis[u] + 1;
q.push( v );
}
}
}
}
inline int _max( int a , int b ){ return a > b ? a : b; }
int main(){
memset( head , 0xff , sizeof head );
prework();
bfs();
int ans = 0;
rep( i , 1 , tot ) ans += ( dis[i] == -1 );
cout << ans << endl;
return 0;
}