HDU 4612 雙聯通分量+樹的直徑

來源:互聯網
上載者:User

標籤:

點擊開啟連結

題意:給一個無向聯通圖,裡面可能有重邊,問添加一條邊後,使得圖中的橋最小,將橋的數量輸出

思路:剛剛讀完題,就有了思路去寫,無非就是將聯通圖雙聯通分量後縮點,然後求一條最長的路,首尾相連,肯定將更多的橋包含使得這些橋不再是橋,很好想的題,但是錯了20+什麼鬼,md重邊這麼難處理,醉了~~~,之前的做法是將重邊全部找出來,希望資料弱點水過去算了,TLE好樣的,那麼我們在處理橋的時候,也就是找橋的時候,如果是橋,我們將這條邊標記一下,然後找所有邊時加上就行了,在一個就是找樹的直徑,兩次bfs就可以,很簡單看看代碼把

#include <queue>#include <vector>#include <stdio.h>#include <string.h>#include <stdlib.h>#include <iostream>#include <algorithm>using namespace std;typedef long long ll;const int inf=0x3f3f3f3f;const int maxn=200010;struct edge{    int to,num;    edge(int a,int b){to=a;num=b;}};vector<edge>G[maxn];vector<int>GG[maxn];int L[maxn],E[maxn],vis[maxn],stack1[maxn];int n,m,k,kk,cnt;void dfs(int x,int fa){    vis[x]=1;L[x]=k;E[x]=k++;stack1[kk++]=x;    int flag=0;    for(unsigned int i=0;i<G[x].size();i++){        edge e=G[x][i];        if(e.to!=fa){            if(!vis[e.to]){                dfs(e.to,x);                L[x]=min(L[x],L[e.to]);                if(L[e.to]>E[x]){                    G[x][i].num=1;                }            }else L[x]=min(L[x],E[e.to]);        }else{            if(flag) L[x]=min(L[x],E[e.to]);            flag++;        }    }    if(L[x]==E[x]){        while(stack1[kk]!=x&&kk>0){            L[stack1[kk-1]]=L[x];            kk--;            vis[stack1[kk]]=0;        }    }}void tarjan(){    kk=0;k=1;dfs(1,1);    for(int i=1;i<=n;i++){        for(unsigned int j=0;j<G[i].size();j++){            edge e=G[i][j];            if(L[i]!=L[e.to]&&e.num==1){                cnt++;                GG[L[i]].push_back(L[e.to]);                GG[L[e.to]].push_back(L[i]);            }        }    }}int dis[maxn],v[maxn];void bfs(int s){    memset(dis,0,sizeof(dis));    memset(v,0,sizeof(v));    v[s]=1;dis[s]=0;    queue<int>que;    que.push(s);    while(!que.empty()){        int u=que.front();que.pop();        for(unsigned int i=0;i<GG[u].size();i++){            int t=GG[u][i];            if(v[t]==0){                v[t]=1;                dis[t]=dis[u]+1;                que.push(t);            }        }    }}int slove(int s){    int max1=0,pos=s;    bfs(s);    for(int i=1;i<=n;i++){        if(dis[i]>max1){            pos=i;max1=dis[i];        }    }    bfs(pos);    int ans=0;    for(int i=1;i<=n;i++){        if(dis[i]>ans) ans=dis[i];    }    return ans;}int main(){    int flag,a,b;    while(scanf("%d%d",&n,&m)!=-1){        if(n==0&&m==0) break;        for(int i=0;i<maxn;i++){            G[i].clear();GG[i].clear();vis[i]=0;        }        for(int i=1;i<=m;i++){            scanf("%d%d",&a,&b);            if(a==b) continue;            G[a].push_back(edge(b,0));            G[b].push_back(edge(a,0));        }        cnt=0;tarjan();        int ans1=slove(1);        printf("%d\n",cnt-ans1);    }    return 0;}

HDU 4612 雙聯通分量+樹的直徑

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.