洛谷5022
题目要求字典序最小,但优先队列贪心显然不对,因为向前走只能访问未访问过的点,若一条路的途中回头的话这条路剩余点再也无法访问了。 数据范围
m
=
=
n
−
1
∣
∣
m
=
=
n
m==n-1||m==n
m = = n − 1 ∣ ∣ m = = n ,即图必是树 或基环树 若图是树,贪心取此时端点更小的分支,然后把这个分支的子树全按此规则搜索即可 若是基环树,可发现无论什么图,最后都会剩下一条边不走。遍历所有边,求最小答案即可
void dfs ( int now, int fa)
{
ans. push_back ( now) ;
vis[ now] = true ;
for ( int i= 0 ; i< edge[ now] . size ( ) ; i++ )
{
int v= edge[ now] [ i] ;
if ( ! vis[ v] && v!= fa&& ! mp[ now] [ v] )
dfs ( v, now) ;
}
return ;
}
void solve ( )
{
memset ( mp, false , sizeof ( mp) ) ;
for ( int i= 1 ; i<= n; i++ )
edge[ F[ i] ] . push_back ( T[ i] ) , edge[ T[ i] ] . push_back ( F[ i] ) ;
for ( int i= 1 ; i<= n; i++ )
sort ( edge[ i] . begin ( ) , edge[ i] . end ( ) ) ;
for ( int i= 0 ; i<= m; i++ )
{
memset ( vis, false , sizeof ( vis) ) ;
ans. clear ( ) ;
mp[ F[ i] ] [ T[ i] ] = mp[ T[ i] ] [ F[ i] ] = true ;
dfs ( 1 , 1 ) ;
mp[ F[ i] ] [ T[ i] ] = mp[ T[ i] ] [ F[ i] ] = false ;
if ( ans. size ( ) < n)
continue ;
if ( an. size ( ) == 0 )
an. assign ( ans. begin ( ) , ans. end ( ) ) ;
else
{
for ( int i= 0 ; i< n; i++ )
{
if ( ans[ i] < an[ i] )
{
an. assign ( ans. begin ( ) , ans. end ( ) ) ;
break ;
}
else if ( ans[ i] > an[ i] )
break ;
}
}
}
for ( it= an. begin ( ) ; it!= an. end ( ) ; it++ )
cout<< * it<< " " ;
cout<< endl;
return ;
}
洛谷2294
差分约束+前缀和
l
,
r
l,r
l , r 月之间收入x,即
s
u
m
[
r
]
−
s
u
m
[
l
−
1
]
=
=
x
sum[r]-sum[l-1]==x
s u m [ r ] − s u m [ l − 1 ] = = x , 同时需满足
−
(
s
u
m
[
r
]
−
s
u
m
[
l
−
1
]
)
=
=
−
x
-(sum[r]-sum[l-1])==-x
− ( s u m [ r ] − s u m [ l − 1 ] ) = = − x 建边跑spfa板子即可