• <ins id="pjuwb"></ins>
    <blockquote id="pjuwb"><pre id="pjuwb"></pre></blockquote>
    <noscript id="pjuwb"></noscript>
          <sup id="pjuwb"><pre id="pjuwb"></pre></sup>
            <dd id="pjuwb"></dd>
            <abbr id="pjuwb"></abbr>

            The Fourth Dimension Space

            枯葉北風(fēng)寒,忽然年以殘,念往昔,語默心酸。二十光陰無一物,韶光賤,寐難安; 不畏形影單,道途阻且慢,哪曲折,如渡飛湍。斬浪劈波酬壯志,同把酒,共言歡! -如夢(mèng)令

            ZOJ 2588-Burning Bridges(圖的連通性問題——求割邊)

            今天想看看關(guān)于橋的求法,搜到了這樣一個(gè)題,由與網(wǎng)上缺少相關(guān)的資料,花了很多時(shí)間在找資料上,最后發(fā)現(xiàn)lrj的書上有這個(gè)問題的描述:
            無向圖的割點(diǎn)和橋(見lrj書)

            算法基于以下原理:(1)如果根頂點(diǎn)的兒子數(shù)大于1,則根頂點(diǎn)是割點(diǎn)(2)如果一個(gè)點(diǎn)和這個(gè)點(diǎn)的子孫都不存在指向這個(gè)點(diǎn)祖先的后向邊,則這個(gè)點(diǎn)為割點(diǎn)。實(shí)現(xiàn)時(shí)需要對(duì)每個(gè)結(jié)點(diǎn)記錄一個(gè)low值,表示該結(jié)點(diǎn)的子孫能夠到達(dá)的最小的深度,如果這個(gè)值小于或等于該點(diǎn)的深度,則該點(diǎn)為割點(diǎn)。如果

            y是x的兒子并且y的low值大于x的深度,則邊(x,y)為圖的橋。

            原來求割點(diǎn)和求割邊是同一回事,難怪網(wǎng)上只有割點(diǎn)的資料,割邊的幾乎沒有提及。具體的算法看lrj的書,這里說一下做題的心得。

            主要是兩個(gè)方面:
            1。題目中給出的圖是有重邊的,如何判斷重邊?這個(gè)問題很重要 根據(jù)題意,沒法確定重邊中的那一條邊會(huì)被燒掉,所以重邊一定不是我們想要的結(jié)果,要從求出的橋里面剔除。我想了比較長的時(shí)間,開矩陣吧,10000*10000的矩陣雖然定位是O(1)的,但是這么大的矩陣肯定爆。
            所以只能用鄰接表。可鄰接表如何判重,難道線性掃描一遍?每一次加邊都要從表頭掃到表尾,然后才能實(shí)現(xiàn)插入,最壞的情況是0+1+2+3+...+m-1=O(m^2)。(當(dāng)然這有點(diǎn)極端,畢竟n只有10000級(jí)別,是邊的十分之一)建立鄰接表的復(fù)雜度就有點(diǎn)。。。另外 20個(gè)case。。。
            但是事實(shí)上,這道題我就是這么做的,鄰接表+內(nèi)存池,線性掃描判重,用的時(shí)間大約是時(shí)限的五分之一。。。可以接受。。。

            2。這個(gè)題中給出的是無向邊,建鄰接表的時(shí)候正反都要建,但是一但正向被搜索過,方向就定了,DFS的過程實(shí)際就是將一個(gè)無向圖,轉(zhuǎn)換成一個(gè)有根的有向的深度優(yōu)先生成樹的過程。所以,每考察一個(gè)節(jié)點(diǎn)就要記錄下他的父親節(jié)點(diǎn),不能將父子邊當(dāng)成回邊,這個(gè)要特別注意。然后就是
            low[ p->t ]> dfsn[k]
            重邊的時(shí)候要特殊照顧,其余的就是標(biāo)準(zhǔn)的算法過程了。

            另外要使用鄰接表的時(shí)候,不要用vector,效率實(shí)在太低,指針+內(nèi)存池才是王道!
            //This is the source code for ZOJ 2588
            //Coded By abilitytao
            //2009年9月26日
            #include<stdio.h>
            #include
            <string.h>
            #include
            <stdlib.h>

            #define DOTMAX 10001
            #define EDGEMAX 100001
            #define min(a,b) ( (a)<(b)?(a):(b) )
            int cmp(const void *a,const void *b)
            {

                
            return (*(int*)a)-(*(int*)b);
            }

            struct node
            {
                
            int t;
                
            int index;
                
            int num;
                node 
            *next;
            }
            dotset[EDGEMAX*2];
            node hash[DOTMAX];
            int record[EDGEMAX];

            int count=0;
            node 
            *Newnode()
            {
                node 
            *p;
                p
            =&dotset[count];
                count
            ++;
                
            return p;
            }

            void init(int n)
            {
                
            int i;
                
            for(i=1;i<=n;i++)
                
            {
                    hash[i].next
            =NULL;
                    hash[i].t
            =-1;
                }

            }


            void inputcase(int n,int m)
            {
                
            int flag;
                
            int i;
                init(n);
                
            int a,b;
                node 
            *p;
                node 
            *q;
                
            for(i=1;i<=m;i++)
                
            {
                    flag
            =0;
                    scanf(
            "%d%d",&a,&b);
                    
            for(p=&hash[a];p->next!=NULL;p=p->next)
                    
            {
                        
                        
            if(p->t==b&&p->num==1)
                        
            {
                            flag
            =1;
                            
            break;
                        }

                        
            else if(p->t==b&&p->num==0)
                        
            {
                            flag
            =1;
                            p
            ->num+=1;
                            
            break;
                        }

                    }

                    
            if(flag==1)
                        
            continue;
                    
            while(p->next!=NULL)
                    
            {
                        p
            =p->next;
                    }

                    q
            =Newnode();
                    q
            ->t=b;
                    q
            ->index=i;
                    q
            ->num=0;
                    q
            ->next=NULL;

                    p
            ->next=q;
                    
            //////////////////////////////////////////////////////////////////////////

                    p
            =&hash[b];

                    q
            =Newnode();
                    q
            ->index=i;
                    q
            ->t=a;
                    q
            ->num=0;

                    q
            ->next=p->next;
                    p
            ->next=q;
                }



            }




            int res=0;
            void dfs( int father,int k,int s,int &cnt,node hash[],bool visit[],int dfsn[],int low[])
            {
                
            ++cnt;
                dfsn[k]
            = cnt, low[k]= cnt, visit[k]= true;
                
                
            int num= 0;
                node 
            *p;
                
            for( p=hash[k].next ;p!=NULL; p=p->next )
                
            {
                    
            if(p->t==father)
                        
            continue;
                    
            if!visit[ p->t ] )
                    
            {
                        num
            ++;
                        dfs(k,p
            ->t,s,cnt,hash,visit,dfsn,low );
                        
                        low[k]
            = min( low[k], low[ p->t ] );
                        
                        
            if( low[ p->t ]> dfsn[k] )  
                        
            {
                            
            if(p->num==0)
                            
            {
                                res
            ++;
                                record[res]
            =p->index;
                            }

                        }

                    }

                    
            else if(k!=p->t)
                        low[k]
            = min( low[k], dfsn[ p->t ] );
                }

            }



            int FindKeyPoint(node hash[],int s,int n)
            {
                
                
            int cnt=0;
                
            bool visit[DOTMAX]={false};
                
            int low[DOTMAX]={0};
                
            int dfsn[DOTMAX]={0};
                dfs(
            -1,s,s,cnt,hash,visit,dfsn,low);
                
            return res;
            }




            int main()
            {

                
            int testcase;
                scanf(
            "%d",&testcase);
                
            int i,j;
                
            int n,m;
                
            int num;
                
            for(i=1;i<=testcase;i++)
                
            {
                    res
            =0;
                    count
            =0;
                    scanf(
            "%d%d",&n,&m);
                    inputcase(n,m);
                    num
            =FindKeyPoint(hash,1,n);
                    qsort(record
            +1,num,sizeof(record[0]),cmp);
                    printf(
            "%d\n",num);
                    j
            =1;
                    
            for(j=1;j<num;j++)
                    
            {
                        printf(
            "%d ",record[j]);
                    }

                    
            if(num!=0)
                        printf(
            "%d\n",record[j]);
                    
            if(i!=testcase)
                        printf(
            "\n");
                }

                
            return 0;
            }

            posted on 2009-09-26 01:35 abilitytao 閱讀(1505) 評(píng)論(0)  編輯 收藏 引用


            只有注冊(cè)用戶登錄后才能發(fā)表評(píng)論。
            網(wǎng)站導(dǎo)航: 博客園   IT新聞   BlogJava   博問   Chat2DB   管理


            久久精品欧美日韩精品| 久久久久人妻精品一区| 久久99热国产这有精品| 亚洲精品乱码久久久久久| 久久夜色精品国产| 久久93精品国产91久久综合| 日本免费一区二区久久人人澡| 久久久久亚洲av无码专区喷水| 久久精品视频一| 一本久久综合亚洲鲁鲁五月天| 久久精品国产亚洲Aⅴ香蕉 | 91精品国产高清久久久久久91| 久久无码AV中文出轨人妻| 性做久久久久久免费观看| 亚洲国产精品无码久久九九| 色天使久久综合网天天 | 久久国产精品成人免费| 国内精品人妻无码久久久影院| 久久精品人人做人人妻人人玩| 精品国产一区二区三区久久久狼| 久久久久亚洲Av无码专| 国产亚洲欧美成人久久片| 国产精品激情综合久久| 久久人人爽人人爽人人片AV东京热| 欧美亚洲另类久久综合婷婷| 亚洲一区精品伊人久久伊人| 久久久久久精品久久久久| 亚洲香蕉网久久综合影视 | 国产精品久久久久AV福利动漫| 伊人久久大香线蕉av一区| 久久天天躁狠狠躁夜夜躁2O2O | 久久91综合国产91久久精品| 国产高潮国产高潮久久久91 | 热久久最新网站获取| 亚洲国产精品无码久久一区二区| 国产三级久久久精品麻豆三级| 久久香蕉一级毛片| 国产精品美女久久福利网站| 国产精品久久久久国产A级| 久久五月精品中文字幕| 一本色道久久88—综合亚洲精品|