题目的意思是要我们去掉最多的边使图还是连通的,同了强连通分支的算法。如下:
#include <stdio.h>
const int LEN = 5005;
struct HEAD { int state; //搜索状态 int fa; //在堆栈中的位置 int du; int next; int last; }; HEAD head1[LEN]; //原图 HEAD head2[LEN]; //新图
struct NODE { int num; int other; //记录还有一条边的位置 int used; //是否可用 int next; }node[LEN*8]; int next_n;
int bridge[LEN/2]; //记录桥的位置 int next_b;
void init_m ( HEAD head[], int n ) {
for ( int i=0; i<n; i++ ) { head[i].state = 0; head[i].next = -1; head[i].du = 0; } }
inline void ins ( HEAD head[], int a, int b ) {
node[next_n].next = -1; node[next_n].num = b; next_n ++;
if ( head[a].next==-1 ) head[a].next = next_n-1; else node[ head[a].last ].next = next_n-1; head[a].last = next_n-1; head[a].du ++; }
int ser ( HEAD head[], int far, int p, int depth ) //找桥 {
head[p].state = 1;
int fa = depth; head[p].fa = depth; for ( int i=head[p].next; i!=-1; i=node[i].next ) { int e = node[i].num; if ( head[e].state==1&&e!=far ) { if ( fa>head[e].fa ) fa = head[e].fa; } else if ( head[e].state==0 ) { int sonfa = ser ( head, p, e, depth+1 ); if ( sonfa>depth ) bridge[next_b++] = i; if ( fa>sonfa ) fa = sonfa; } } head[p].state = 2;
return fa; }
void ser2 ( HEAD head[], int p, int color ) {
head[p].state = 1;
head[p].fa = color; for ( int i=head[p].next; i!=-1; i=node[i].next ) { int e = node[i].num; if ( !node[i].used&&!head[e].state ) ser2 ( head, e, color ); }
head[p].state = 2; }
int work ( int n ) {
//找桥 next_b = 0; ser ( head1, -1, 0, 0 ); for ( int i=0; i<next_b; i++ ) { int p = bridge[i]; node[p].used = 1; node[ node[p].other ].used = 1; } //求连通分块 for ( int i=0; i<n; i++ ) head1[i].state = 0; int color = 0; for ( int i=0; i<n; i++ ) { if ( !head1[i].state ) ser2 ( head1, i, color++ ); } //建图 init_m ( head2, color ); for ( int i=0; i<n; i++ ) for ( int j=head1[i].next; j!=-1; j=node[j].next ) { int a = i; int b = node[j].num; if ( head1[a].fa!=head1[b].fa ) { ins ( head2, head1[a].fa, head1[b].fa ); } } int ans = 0; for ( int i=0; i<color; i++ ) { if ( head2[i].du==1 ) ans ++; } return (ans+1)/2; }
int main () {
int n, m; scanf ( "%d%d", &n, &m ); next_n = 0; init_m ( head1, n ); for ( int i=0; i<m; i++ ) { int a, b; scanf ( "%d%d", &a, &b ); ins ( head1, a-1, b-1 ); node[next_n-1].other = next_n; ins ( head1, b-1, a-1 ); node[next_n-1].other = next_n-2; }
printf ( "%d\n", work ( n ) ); return 0; }
|
|
| 日 | 一 | 二 | 三 | 四 | 五 | 六 |
---|
25 | 26 | 27 | 28 | 29 | 30 | 31 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 1 | 2 | 3 | 4 | 5 |
|
公告
决定从线程开始!!
常用链接
留言簿(6)
随笔档案
搜索
最新评论
阅读排行榜
评论排行榜
|
|