• <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>

            M.J的blog

            algorithm,ACM-ICPC
            隨筆 - 39, 文章 - 11, 評(píng)論 - 20, 引用 - 0
            數(shù)據(jù)加載中……

            TOJ 3446.Money Matters 并查集,路徑壓縮

                    題目大意是N個(gè)人互相有債a[i](正的表示別人欠錢(qián),否則表示自己欠別人錢(qián),a[i]的和保證為0),但是這N個(gè)人只有朋友間才能互相算帳,現(xiàn)在給出N個(gè)人的債,并且給出M個(gè)關(guān)系,即誰(shuí)和誰(shuí)是朋友,最后問(wèn)有沒(méi)有可能所有人都把帳算清。


            Sample Input 1:                         Sample Input 2:

            5    3                                            4     2
            100                                              15
            -75                                               20
            -25                                              -10
            -42                                              -15
            42                                                0  2
            0 1                                               1  3
            1 2
            3 4

            Sample Output 1:                       Sample Output  2:

            POSSIBLE                                    IMPOSSILBE

             思路1:

                          每輸入一個(gè)關(guān)系,合并,最后從1到N,對(duì)于每一個(gè)人,找出它們的祖先,將他們的債debt加到祖先的debt

                          上。通俗的講,就是每個(gè)集合的成員都將自己的debt加到祖先上,自己歸0,最后看祖先的值是否為0;

                          最后在從1到N掃一遍如果有debt不為0的,輸出“IMPOSSIBLE”,否則“POSSIBLE”;

                          缺點(diǎn):復(fù)雜度高,查詢(xún)復(fù)雜度*N,最后勉強(qiáng)過(guò)了,時(shí)間0.63s

            思路2:

                          路徑壓縮,每輸入一個(gè)關(guān)系,合并。最后從1到N,如果 i 的debt不為0,從 i 到 i 的祖先的路徑不斷壓縮直到

                          祖先,這樣雖然仍然是N次操作,但由于在壓縮過(guò)程中大部分成員debt歸0,故實(shí)際上進(jìn)行操作的次數(shù)遠(yuǎn)小于N.

                          最后時(shí)間為0.11,比起上一種方法有了很大提高

            Code 1:

            #include <cstdio>
            #include 
            <cstring>
            struct Node{
                    
            int father,v,num;
            }a[
            10002];
            int find(int n){
                    
            int tep,m = n;
                    
            while(n != a[n].father)
                            n 
            = a[n].father;
                    
            while(m != n){
                            tep 
            = a[n].father;
                            a[n].father 
            = n;
                            m 
            = tep;
                    }
                    
            return n;
            }
            void Union(int root1,int root2){
                    
            int t1,t2;
                    t1 
            = find(root1),t2 = find(root2);
                    
            if(t1 == t2) return ;
                    
            else{
                            
            if(a[t1].v > a[t2].v){
                                    a[t1].v 
            += a[t2].v;
                                    a[t2].father 
            = t1;
                            }
                            
            else{
                                    a[t2].v 
            += a[t1].v;
                                    a[t1].father 
            = t2;
                            }
                    }
            }
            int main()
            {
                    
            int n,m,i,j;
                    
            bool flag = false;
                    scanf(
            "%d%d",&n,&m);
                    
            for(i = 0;i < n; ++i){
                            a[i].father 
            = i,a[i].v = 0;
                            scanf(
            "%d",&a[i].num);
                    }
                    
            while(m--){
                            scanf(
            "%d%d",&i,&j);
                            Union(i,j);
                    }
                    
            for(i = 0;i < n; ++i){
                            
            int tep = find(i);
                            
            int tt = a[i].num;
                            a[i].num 
            -= tt;
                            a[tep].num 
            += tt;
                    }
                    
            for(i = 0;i < n; i++)
                            
            if(a[i].num != 0){
                                    flag 
            = true;
                                    
            break;
                            }
                    
            if(flag) printf("IMPOSSIBLE\n");
                    
            else     printf("POSSIBLE\n");
            }

            Code 2:

            #include <cstdio>
            #include 
            <cstring>
            struct Node{
                    
            int father,v,num;
            }a[
            10002];
            int find(int n){
                    
            int m = n,tep;
                    
            while(n != a[n].father)
                            n 
            = a[n].father;
                    
            while(m != n){
                            tep 
            = a[m].father;
                            
            int tt = a[m].num;
                            a[m].num 
            -= tt;
                            a[tep].num 
            += tt;
                            a[m].father 
            = n;
                            m 
            = tep;
                    }
                    
            return n;
            }
            void Union(int root1,int root2){
                    
            int t1,t2;
                    t1 
            = find(root1),t2 = find(root2);
                    
            if(t1 == t2) return ;
                    
            else{
                            
            if(a[t1].v > a[t2].v){
                                    a[t1].v 
            += a[t2].v;
                                    a[t2].father 
            = t1;
                            }
                            
            else{
                                    a[t2].v 
            += a[t1].v;
                                    a[t1].father 
            = t2;
                            }
                    }
            }
            int main()
            {
                    
            int n,m,i,j;
                    
            bool flag = false;
                    scanf(
            "%d%d",&n,&m);
                    
            for(i = 0;i < n; ++i){
                            a[i].father 
            = i,a[i].v = 0;
                            scanf(
            "%d",&a[i].num);
                    }
                    
            while(m--){
                            scanf(
            "%d%d",&i,&j);
                            Union(i,j);
                    }
                    
            for(i = 0;i < n; ++i)
                         
            if(a[i].num != 0) find(i);
                    
            for(i = 0;i < n; i++)
                            
            if(a[i].num != 0){
                                    flag 
            = true;
                                    
            break;
                            }
                    
            if(flag) printf("IMPOSSIBLE\n");
                    
            else     printf("POSSIBLE\n");
            }








            posted on 2010-07-05 21:08 M.J 閱讀(311) 評(píng)論(0)  編輯 收藏 引用


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


            亚洲а∨天堂久久精品| 无码久久精品国产亚洲Av影片| 伊人色综合九久久天天蜜桃| 国内精品久久九九国产精品| 日韩精品无码久久久久久| 久久精品综合网| 一级做a爰片久久毛片毛片| 久久亚洲电影| 深夜久久AAAAA级毛片免费看 | 久久偷看各类wc女厕嘘嘘| 久久WWW免费人成一看片| 久久天天躁夜夜躁狠狠躁2022 | 九九热久久免费视频| 日本久久久久久中文字幕| 99久久综合狠狠综合久久| 国产精品美女久久久免费| 天天影视色香欲综合久久| 伊人久久成人成综合网222| 99久久精品免费看国产一区二区三区| 狠狠色丁香久久婷婷综合| 久久国产精品成人片免费| 97久久精品午夜一区二区| 国内精品久久久久久不卡影院| 久久国产午夜精品一区二区三区| 久久亚洲色一区二区三区| 伊人久久综合无码成人网| 69久久精品无码一区二区| 久久亚洲中文字幕精品一区四| 久久久噜噜噜久久中文字幕色伊伊| 亚洲精品无码久久久久去q| 97久久香蕉国产线看观看| 欧美久久久久久精选9999| 欧美黑人激情性久久| 国产A级毛片久久久精品毛片| 久久久午夜精品福利内容| 国内精品久久久久久99蜜桃| 久久免费视频6| 国内精品久久久久久久97牛牛| 久久久久久毛片免费看| 日产精品久久久久久久性色| 久久久精品视频免费观看|