hdu 4005 雙聯通 2011大連賽區網路賽E *****

來源:互聯網
上載者:User

標籤:

題意:

有一幅圖,現在要加一條邊,加邊之後要你刪除一條邊,使圖不連通,費用為邊的費用,要你求的是刪除的邊的最小值的最大值(每次都可以刪除一條邊,選最小的刪除,這些最小中的最大就為答案)

首先要進行縮點,把圖縮為一棵樹,因此,加入一條邊後圖就會存在一個環,環中的任何一條邊刪除後都不會導致圖不連通

之後找一條最小的邊,可以說這條邊肯定是在加邊之後的連通塊裡的,因為如果不在連通塊裡,那就直接可以把這條最小的邊刪掉,而達不到求出答案的目的

找到邊後,分別從邊的兩點開始遍曆,要遍曆出一條路徑來,並且邊上的權值要儘可能的小,因為這樣才能讓不在環中的邊儘可能的大,然後,答案就是每個 節點的次小兒子的最小值,如果沒有次小兒子就不能算(就是說只有一個兒子,即節點不是三叉的),因為我完全可以把它和最小的邊放到一個連通塊中,那樣答案 就應該更大了。

終上所述:先進行無向圖的縮點,再在樹上找最小的邊,最後分別從邊的兩點出發,遍曆樹,找節點的次小兒子節點中的最小值

舉個簡單的例子(括弧內的數字代表邊上的權值)1和8間的權值為1,是最小的

                     1---8

                  /           \(3) 

        (2)/               \

             2                  3

    (4) /       \(5)    (6)/      \(7)

       /           \         /          \

     4              5     6              7

左子樹中2的子節點有次小值5,右子樹中3的子節點次小值為7,兩個次小值間的最小值是5,即答案

現在,比如所你要把3、4連起來。我可以去掉2、5之間的邊讓圖不連通,花費為5

把3、5連起來,我自然可以刪掉2、4,花費為4,

一個節點的次小值和最小值(比如說4、5兩點)不可能被同時連進一個連通塊(或環)中(因為必須把最小的那條邊加進環中),正是利用這個性質,不管 把那兩個點連起來,我們都可以找到一個最小值或次小值來刪掉使圖不連通,注意:再重複一遍,同一個節點的最小值和次小值不會被加進同一個環,因此,這些次 小值中的最小的那條邊的權值就是答案。(這時你如果把次小的邊加進環中,如2--5,自然可以刪掉一條更小的邊 如2--4 使圖不連通,相反,如果沒有把次小的邊加進去,那次小的就是答案)

 

思路是次要,代碼要能搞出來

 

  1 #include<cstdio>  2 #include<cstring>  3 #include<stack>  4 #include<algorithm>  5 #define N 20100  6 #define M 200100  7 #define inf 100000000  8 #pragma comment(linker, "/STACK:1024000000,1024000000")  9 using namespace std; 10 int head1[N],head2[N],cnt,scc,Min; 11 int dfn[N],low[N],belong[N]; 12 int dp[N]; 13 stack<int>sta; 14 struct Edge{ 15     int v,w,next; 16 }edge[M*4]; 17  18 void addedge(int u,int v,int w,int *head){ 19     edge[cnt].v=v; 20     edge[cnt].w=w; 21     edge[cnt].next=head[u]; 22     head[u]=cnt++; 23     edge[cnt].v=u; 24     edge[cnt].w=w; 25     edge[cnt].next=head[v]; 26     head[v]=cnt++; 27 } 28 void init(int n){ 29     memset(head1,-1,sizeof(head1)); 30     memset(head2,-1,sizeof(head2)); 31     memset(dfn,0,sizeof(dfn)); 32     for(int i=1;i<=n;i++)dp[i]=inf; 33     cnt=scc=0; 34 } 35 void DP(int u,int fa){ 36     int i; 37     for(i=head2[u];i!=-1;i=edge[i].next){ 38         int v=edge[i].v; 39         if(v!=fa){ 40             DP(v,u); 41             dp[v]=min(dp[v],edge[i].w); 42             if(dp[u]>dp[v]){ 43                 Min=min(Min,dp[u]); 44                 dp[u]=dp[v]; 45             } 46             else 47                 Min=min(Min,dp[v]); 48         } 49     } 50 } 51 void tarjan(int u,int fa){ 52     int i,flag=1; 53     dfn[u]=low[u]=dfn[fa]+1; 54     sta.push(u); 55     for(i=head1[u];i!=-1;i=edge[i].next){ 56         int v=edge[i].v; 57         if(v==fa && flag){ 58             flag=0; 59             continue; 60         } 61         if(dfn[v]==0){ 62             tarjan(v,u); 63             low[u]=min(low[u],low[v]); 64         } 65         else 66             low[u]=min(low[u],dfn[v]); 67     } 68     if(dfn[u]==low[u]){ 69         scc++; 70         while(1){ 71             int tem=sta.top(); 72             sta.pop(); 73             belong[tem]=scc; 74             if(tem==u)break; 75         } 76     } 77 } 78 int main(){ 79     int i,n,m; 80     int u,v,w; 81     while(scanf("%d %d",&n,&m)==2){ 82         init(n); 83         for(i=1;i<=m;i++){ 84             scanf("%d %d %d",&u,&v,&w); 85             addedge(u,v,w,head1); 86         } 87         for(i=1;i<=n;i++) 88             if(dfn[i]==0) 89                 tarjan(1,0); 90         if(scc==1){ 91             printf("-1\n"); 92             continue; 93         } 94         int last=cnt,whi; 95         Min=inf; 96         for(i=0;i<last;i+=2){ 97             if(belong[edge[i].v]!=belong[edge[i^1].v]){ 98                 addedge(belong[edge[i].v],belong[edge[i^1].v],edge[i].w,head2); 99                 if(edge[i].w<Min){100                     whi=i;101                     Min=edge[i].w;102                 }103             }104         }105         Min=inf;106         DP(belong[edge[whi].v],belong[edge[whi^1].v]);107         DP(belong[edge[whi^1].v],belong[edge[whi].v]);108         if(Min==inf)printf("-1\n");109         else printf("%d\n",Min);110     }111     return 0;112 }

 

hdu 4005 雙聯通 2011大連賽區網路賽E *****

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在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.