hdu4612Warm up(双联通缩点+树直径)
来源:互联网 发布:人工智能概念股及代码 编辑:程序博客网 时间:2024/06/15 01:23
借鉴这里:http://blog.csdn.net/softshell/article/details/9496161
有N个点,M条边(有重边)的无向图,这样图中会可能有桥,问加一条边后,使桥最少,求最少桥的数量。
缩点后,求出图中的桥的个数,然后重建图必为树,求出树的最长直径,在该直径的两端点连一边,则图中的桥会最少。
双联通缩点有很多不懂滴地方。。。不咋明白。。。问题之一。。vis数组用不用写。。唉。。唉。。
#pragma comment(linker, "/STACK:1024000000,1024000000")#include<iostream>#include<cstdio>#include<cstdlib>#include<cstring>#include<queue>using namespace std;#define clr(x) memset(x,0,sizeof(x))#define maxn 300015#define maxm 4000015struct node{ int to,next;}e[maxm],e2[maxm];int head[maxn],tot;int head2[maxn],tot2;int col[maxn],dfn[maxn],low[maxn],sta[maxn];int top,ti,scc; //scc 双联通分支个数int n,m;bool vis[maxn];void init(){ memset(head,-1,sizeof(head)); clr(vis); clr(dfn); tot=0; top=0; scc=ti=0;}void add(int u,int v){ e[tot].to=v; e[tot].next=head[u]; head[u]=tot++;}void add2(int u,int v){ e2[tot2].to=v; e2[tot2].next=head2[u]; head2[u]=tot2++;}void tarjan(int u,int fa){ dfn[u]=low[u]=++ti; sta[++top]=u; vis[u]=true; int cnt=0; for(int i=head[u];i!=-1;i=e[i].next){ int v=e[i].to; if(!dfn[v]){ tarjan(v,u); low[u]=min(low[u],low[v]); } else if(fa==v){ if (cnt) low[u] = min(low[u],dfn[v]);//重边 cnt++; } else if(vis[v])low[u]=min(low[u],dfn[v]); } if(dfn[u]==low[u]){ int x; scc++; do{ x = sta[top--]; vis[x]=false; col[x] = scc; }while(x!=u); }}void build(){ tot2 = 0; memset(head2,-1,sizeof(head2)); for(int i = 1; i <= n; i++){ for(int j = head[i]; j!=-1; j = e[j].next){ int v = e[j].to; if(col[i]!=col[v]) add2(col[i],col[v]); } }}int r;//直径int bfs(int x){ queue<int>q; int dis[maxn]; int end; memset(dis,-1,sizeof(dis)); q.push(x); dis[x]=0; while(!q.empty()){ int u=q.front(); q.pop(); r=dis[u]; end=u; for(int i=head2[u];i!=-1;i=e2[i].next){ int v=e2[i].to; if(dis[v]==-1){ dis[v]=dis[u]+1; q.push(v); } } } return end;}int main(){ int u,v; while(scanf("%d%d",&n,&m)!=EOF){ init(); if(n==0&&m==0)break; for(int i=0;i<m;i++){ scanf("%d%d",&u,&v); if(v==u)continue; add(u,v); add(v,u); } tarjan(1,-1); build(); r=0; bfs(bfs(1)); printf("%d\n",scc-r-1); } return 0;}
- hdu4612Warm up(双联通缩点+树直径)
- hdu4612(双联通缩点+求树的直径)
- hdu4612warm up(双连通分量+缩点+最长链)
- HDU 4612 Warm up (边双联通,树的直径)
- HDU 4612 Warm up (树的直径 + 双联通)
- hdu 4612 Warm up(缩点+树直径)
- HDU 4612 Warm up(边双联通求树的直径)
- HDOJ 题目4612Warm up(双联通求桥数,缩点求树的直径)
- HDU 4612 Warm up (缩点+树的直径,有重边)
- hdu 4612 Warm up (边双联通分量缩点)
- Gym 100712H(边双联通+树的直径)
- hdu 4612 Warm up(边-双连通+缩点+树的直径)
- Warm up(hdu4612双连通分量+缩点+树的直径)
- Warm up 【tarjan 求EBC+求桥+缩点+树的直径】
- hdu 4612 Warm up 双连通缩点+树的直径
- Hdu 4612 Warm up (双连通缩点+树的直径)
- HDU 4612 Warm up(边双联通+直径【手动扩栈】)
- hdu4612Warm up tarjan+树形dp
- 设计模式之工厂模式
- JAVA学习路线
- ORACLE DB_NAME ,GLOBAL_NAME,INSTANCE_NAME,ORACLE_SID,Service_NAME
- HDU 1010 BFS
- Java面试题
- hdu4612Warm up(双联通缩点+树直径)
- 算法分析:二分查找
- 漂亮的Swing界面 --substance.jar
- apache mina框架以及nio学习
- StrutsPrepareAndExecuteFilter
- 小女子的第一次哦
- I NEED A OFFER! 01背包
- 归并排序-求逆序数算法
- PHP汉字转换为拼音