CF Ring road(深搜)
想了N题,甚至重新学习了一遍强连通分支,但事实上,它是用dfs做的,郁闷啊!
题意:有N个城市,原来每个城市之间有一条双向路,但是为了交通安全全都改成了单向路,每条路的费用为ci,求为了使任一城市都能到达其他个城市需要增加路的最小费用。
解题过程:原来是想找一下图中有几个强连通分支,强连通分支中的任意两个城市一定是互达的,缩点后求各点之间的最小费用,不过这个想法连第一个样例都过不了,因为不需要在每两个点之间都建一条路,而是任意两点可以借助其他缩点互达即可,所以缩完点后,还要求一个强连通图最小权值,这个问题暂时还没想到方法,所以只好放弃。参考了一下别人的思路,似乎都是用dfs做的,其实也很简单,只是没想到,就是将正向的费用设为0 ,逆向的费用设为ci,这样就是一个无向图了,然后通过dfs搜索所有的通路,找最小值。
代码:
View Code
#include <stdio.h> #include <stdlib.h> #include <string.h> #include <iostream> #include <algorithm> #include <queue> #define N 105 using namespace std ; int map[N][N] ; int n ; int find( int x , int y ) { int i ; if ( x == 1 ) return 0 ; for ( i = 1 ; i <= n ; i++ ) if ( i != y && ( map[x][i] != -1 )) return find ( i , x ) + map[x][i] ; } int main() { int i , x , y , z ; //freopen( "input.txt" , "r" , stdin ) ; while ( scanf ( "%d" , &n ) != EOF ) { memset( map , -1 , sizeof(map)) ; for ( i = 1 ; i <= n ; i++ ) { scanf ( "%d%d%d" , &x , &y , &z ); map[x][y] = 0 ;//正向的设为0 map[y][x] = z ;//逆向的设为ci } int sum = 0 ; for ( i = 1 ; i <= n ; i++ ) { if ( map[1][i] != -1 ) { x = sum ;//这里是因为题目中有句话是“each city was connected directly to exactly two other cities” sum = find ( i , 1 ) + map[1][i] ;//dfs搜所有通路 } } printf ( "%d\n" , sum > x ? x : sum ) ;//找出最小的 } return 0 ; }