POJ 3164 Command Network (最小樹形圖-朱劉演算法),poj3164

來源:互聯網
上載者:User

POJ 3164 Command Network (最小樹形圖-朱劉演算法),poj3164

題目地址:POJ 3164
最小樹形圖第一發。
把一個v寫成u了。。。。。TLE了一晚上。。。(雖說今晚出去玩了。。)
剛開始看這個演算法的時看模板以為又是一個isap。。。。嚇得一個哆嗦。但是仔細看了看之後發現還是挺好理解的。寫下自己的理解。
朱劉演算法其實只有3步,然後不斷迴圈。
1:找到每個點的最小入邊。既然是產生樹,那麼對於每個點來說,只要選一個權值最小的入邊就可以了。貪心思想。因為如果不是最小入邊,那麼它肯定不是最小樹形圖的一條邊,考慮它是沒有意義的。
2:找環。找環找的是最小入邊構成的新圖的環。如果沒找到環,那麼一棵樹就已經形成了,因為樹就是沒有環的圖。再因為邊權都是最小的,因此此時最小樹形圖就已經出來了,停止迴圈。
3:如果第2步中找到了環,那麼這個環就可以縮成一個點。然後構造新圖,更新邊權。更新邊權的方法是:假設某點u在該環上,並設這個環中指向u的邊權是in[u],那麼對於每條從u出發的邊(u, i, w),在新圖中串連(new, i, w)的邊,其中new為新加的人工頂點; 對於每條進入u的邊(i, u, w),在新圖中建立邊(i, new, w-in[u])的邊。之所以是w-in[u]的原因是如果選擇了w,那麼那個in[u]在樹中就是多餘的,完全可以刪除,所以需要減去,然後再後面的總費用累加中會體現出刪掉了這個權值,不理解的畫個圖就明白了。
至於實現方法還是看代碼吧。看不懂的可以留言提問。
代碼如下:

#include <iostream>#include <string.h>#include <math.h>#include <queue>#include <algorithm>#include <stdlib.h>#include <map>#include <set>#include <stdio.h>using namespace std;#define LL __int64#define pi acos(-1.0)//#pragma comment(linker, "/STACK:1024000000")const int mod=1e9+7;const int INF=0x3f3f3f3f;const double eqs=1e-9;const int MAXN=40000+10;int cnt, n;int color[110], id[110], pre[110];double in[200];struct Point{        double x, y;}fei[200];struct node{        int u, v;        double w;}edge[11000];void add(int u, int v, double w){        edge[cnt].u=u;        edge[cnt].v=v;        edge[cnt++].w=w;}double dist(Point f1, Point f2){        return sqrt((f1.x-f2.x)*(f1.x-f2.x)*1.0+(f1.y-f2.y)*(f1.y-f2.y));}double dmst(int root){        double ans=0;        int i, j, u, v, NV=n;        while(1){                for(i=1;i<=NV;i++) in[i]=INF;//找最小入邊                for(i=0;i<cnt;i++){                        u=edge[i].u;                        v=edge[i].v;                        if(v!=u&&edge[i].w<in[v]){//更新最下入邊,並設為前驅節點                                in[v]=edge[i].w;                                pre[v]=u;                        }                }                for(i=1;i<=NV;i++){                        if(i!=root&&in[i]==INF) return -1;//有孤立點,不可能產生樹                }                memset(color,-1,sizeof(color));                memset(id,-1,sizeof(id));                in[root]=0;                int tot=0;                for(i=1;i<=NV;i++){                        ans+=in[i];                        u=i;                        while(color[u]!=i&&id[u]==-1&&u!=root){//找環                                color[u]=i;                                u=pre[u];                        }                        if(id[u]==-1&&u!=root){//驚現一隻環!快活捉他。。                                id[u]=++tot;//對發現的環進行編號,相當於縮點後的那個點。                                for(v=pre[u];v!=u;v=pre[v]){                                        id[v]=tot;                                }                        }                }                if(!tot) break;//沒找到環,說明大功告成。那就收拾東西走人吧。。                for(i=1;i<=NV;i++){                        if(id[i]==-1) id[i]=++tot;//對所有點進行編號,一個都不能跑。。                }                for(i=0;i<cnt;i++){//更新邊權,構造新圖                        v=edge[i].v;                        edge[i].u=id[edge[i].u];                        edge[i].v=id[edge[i].v];                        if(edge[i].u!=edge[i].v){                                edge[i].w-=in[v];                        }                }                NV=tot;                root=id[root];//不要忘記更新點數和樹根的編號。。        }        return ans;}int main(){        int m, i, j, u, v;        double ans;        while(~scanf("%d%d",&n,&m)){                for(i=1;i<=n;i++){                        scanf("%lf%lf",&fei[i].x,&fei[i].y);                }                cnt=0;                while(m--){                        scanf("%d%d",&u,&v);                        if(u!=v)                        add(u,v,dist(fei[u],fei[v]));                }                ans=dmst(1);                if(ans==-1) puts("poor snoopy");                else printf("%.2f\n",ans);        }        return 0;}

聯繫我們

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