hdu4612 在无向图中加一条边使桥最少 :tarjan预处理求桥/缩点/树直径
很显然加在缩点后的树直径首尾可以最大限度减少桥的数量==
所以就是个无向图tarjan求桥和bfs求树直径裸题了
明天继续看TUT
1 #pragma comment(linker,"/STACk:10240000,10240000") 2 #include<stdio.h> 3 #include<string.h> 4 #include<algorithm> 5 #include<stack> 6 #include<vector> 7 #include<queue> 8 using namespace std; 9 stack<int>s; 10 queue<int>q; 11 int Now,Head[2000005],Next[2000005],Point[2000005]; 12 int _now,_head[2000005],_next[2000005],_point[2000005]; 13 int pre[200005],lowlink[200005],sccno[200005],ans,vis[200005]; 14 int scc_cnt,dfs_clock,n,iscut[2000005]; 15 void add(int x,int y) 16 { 17 Next[++Now]=Head[x]; 18 Head[x]=Now; 19 Point[Now]=y; 20 } 21 void Add(int x,int y) 22 { 23 _next[++_now]=_head[x]; 24 _head[x]=_now; 25 _point[_now]=y; 26 } 27 void dfs(int u) 28 { 29 pre[u]=lowlink[u]=++dfs_clock; 30 s.push(u); vis[u]=1; 31 for (int i=Head[u];i!=-1;i=Next[i]) 32 if (!iscut[i/2]){ 33 iscut[i/2]=1; 34 int v=Point[i]; 35 if (!pre[v]){ 36 dfs(v); 37 lowlink[u]=min(lowlink[u],lowlink[v]); 38 } 39 else if (vis[u]){ 40 lowlink[u]=min(lowlink[u],pre[v]); 41 } 42 } 43 if (lowlink[u]==pre[u]){ 44 scc_cnt++; 45 while (1){ 46 int x=s.top(); s.pop(); vis[x]=0; 47 sccno[x]=scc_cnt; 48 if (x==u) break; 49 } 50 } 51 } 52 void DAG() 53 { 54 for (int i=1;i<=n;i++) 55 for (int j=Head[i];j!=-1;j=Next[j]){ 56 int v=Point[j]; 57 if (sccno[i]==sccno[v]) continue; 58 ans++; 59 Add(sccno[i],sccno[v]); 60 } 61 } 62 void bfs(int u) 63 { 64 memset(vis,-1,sizeof(vis)); 65 while (!q.empty()) q.pop(); 66 q.push(u); vis[u]=0; 67 while (!q.empty()){ 68 int u=q.front(); q.pop(); 69 for (int i=_head[u];i;i=_next[i]) 70 { 71 int v=_point[i]; 72 if (vis[v]!=-1) continue; 73 vis[v]=vis[u]+1; 74 q.push(v); 75 } 76 } 77 78 } 79 int main() 80 { 81 int m,x,y,i,maxi; 82 while (~scanf("%d%d",&n,&m)&&(m||n)) 83 { 84 memset(sccno,0,sizeof(sccno)); 85 memset(pre,0,sizeof(pre)); 86 memset(Head,-1,sizeof(Head)); 87 memset(_head,0,sizeof(_head)); 88 memset(iscut,0,sizeof(iscut)); 89 memset(vis,0,sizeof(vis)); 90 Now=-1; _now=scc_cnt=dfs_clock=ans=0; 91 while (!s.empty()) s.pop(); 92 while (m--){ 93 scanf("%d%d",&x,&y); 94 add(x,y); add(y,x); 95 } 96 for (i=1;i<=n;i++) if (!pre[i]) dfs(1); 97 DAG(); 98 bfs(1); 99 maxi=1; 100 for (i=1;i<=scc_cnt;i++) 101 if (vis[i]>vis[maxi]) maxi=i; 102 bfs(maxi); 103 maxi=1; 104 for (i=1;i<=scc_cnt;i++) 105 if (vis[i]>vis[maxi]) maxi=i; 106 // for (i=1;i<=n;i++) printf("%d ",sccno[i]); 107 // printf("------%d %d %d\n",ans/2,vis[maxi],scc_cnt); 108 printf("%d\n",ans/2-vis[maxi]); 109 } 110 return 0; 111 }