• <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>
            posts - 7,comments - 3,trackbacks - 0

            Base Station

            Time Limit: 5000/2000 MS (Java/Others)    Memory Limit: 65768/32768 K (Java/Others)
            Total Submission(s): 844    Accepted Submission(s): 353


            Problem Description
            A famous mobile communication company is planning to build a new set of base stations. According to the previous investigation, n places are chosen as the possible new locations to build those new stations. However, the condition of each position varies much, so the costs to built a station at different places are different. The cost to build a new station at the ith place is Pi (1<=i<=n).

            When complete building, two places which both have stations can communicate with each other.

            Besides, according to the marketing department, the company has received m requirements. The ith requirement is represented by three integers Ai, Bi and Ci, which means if place Aand Bi can communicate with each other, the company will get Ci profit.

            Now, the company wants to maximize the profits, so maybe just part of the possible locations will be chosen to build new stations. The boss wants to know the maximum profits.
             

            Input
            Multiple test cases (no more than 20), for each test case:
            The first line has two integers n (0<n<=5000) and m (0<m<=50000).
            The second line has n integers, P1 through Pn, describes the cost of each location.
            Next m line, each line contains three integers, Ai, Bi and Ci, describes the ith requirement.
             

            Output
            One integer each case, the maximum profit of the company.
             

            Sample Input
            5 5 1 2 3 4 5 1 2 3 2 3 4 1 3 3 1 4 2 4 5 3
             

            Sample Output
            4
             

            Author
            liulibo
             

            Source
             

            Recommend
            lcy
             
            論文題,Amber最小割模型里面的,最大權閉合圖,因為數組開的太大了,吃了一次RE......
            最大權閉合圖不用說了,邊看成收益點,連向S,流量是點權,站點看成花費點,連向T,流量也是點權,其他按照原圖連邊,流量是無限大,之后做一次最小割,割值就是你未選的收益點+選定花費點(因為是閉合圖,所以割肯定是簡單割,想一下割的定義,就明白割值的含義了),用你總收益-割值,就是答案。
            用SAP求的最小割,漸漸愛上SAP了,Dinic不用了.....
            代碼:

            #include <cstdio>
            #include 
            <cstring>
            #include 
            <iostream>
            #include 
            <queue>
            using namespace std;

            const int maxnode = 60000;
            const int maxedge = 320000;
            const long long inf = (1LL << 35);

            int S, T, cnt;
            int head[maxnode], gap[maxnode], pre[maxnode], cur[maxnode], dis[maxnode];

            struct Edge
            {
                
            int s, t;
                
            int next;
                
            long long w;
            } st[maxedge];

            void init()
            {
                memset(head, 
            -1sizeof(head));
                cnt 
            = 0;
            }

            void AddEdge(int s, int t, long long w)
            {
                st[cnt].s 
            = s;
                st[cnt].t 
            = t;
                st[cnt].w 
            = w;
                st[cnt].next 
            = head[s];
                head[s] 
            = cnt;
                cnt
            ++;

                st[cnt].s 
            = t;
                st[cnt].t 
            = s;
                st[cnt].w 
            = 0;
                st[cnt].next 
            = head[t];
                head[t] 
            = cnt;
                cnt
            ++;
            }

            void bfs()
            {
                memset(gap, 
            0sizeof(gap));
                memset(dis, 
            -1sizeof(dis));
                queue 
            <int> Q;
                Q.push(T);
                dis[T] 
            = 0;
                gap[
            0= 1;
                
            int k, t;
                
            while (!Q.empty())
                {
                    k 
            = Q.front();
                    Q.pop();
                    
            for (int i = head[k]; i != -1; i =st[i].next)
                    {
                        t 
            = st[i].t;
                        
            if (dis[t] == -1 && st[i ^ 1].w > 0)
                        {
                            dis[t] 
            = dis[k] + 1;
                            gap[dis[t]]
            ++;
                            Q.push(t);
                        }
                    }
                }
            }

            long long sap()
            {
                
            int i;
                
            for (i = S; i <= T; ++i)
                    cur[i] 
            = head[i];
                pre[S] 
            = S;
                
            int u = S, v;
                
            long long flow = 0;
                
            long long aug = inf;
                
            bool flag;
                
            while (dis[S] <= T)
                {
                    flag 
            = false;
                    
            for (i = cur[u]; i != -1; i = st[i].next)
                    {
                        v 
            = st[i].t;
                        
            if (st[i].w > 0 && dis[u] == dis[v] + 1)
                        {
                            cur[u] 
            = i;
                            flag 
            = true;
                            pre[v] 
            = u;
                            aug 
            = (aug > st[i].w) ? st[i].w : aug;
                            u 
            = v;
                            
            if (v == T)
                            {
                                flow 
            += aug;
                                
            for (u = pre[u]; v != S; u = pre[u])
                                {
                                    v 
            = u;
                                    st[cur[u]].w 
            -= aug;
                                    st[cur[u] 
            ^ 1].w += aug;
                                }
                                aug 
            = inf;
                            }
                            
            break;
                        }
                    }
                    
            if (flag == truecontinue;
                    
            int mint = T;
                    
            for (i = head[u]; i != -1; i = st[i].next)
                    {
                        v 
            = st[i].t;
                        
            if (st[i].w > 0 && mint > dis[v])
                        {
                            cur[u] 
            = i;
                            mint 
            = dis[v];
                        }
                    }
                    gap[dis[u]]
            --;
                    
            if (gap[dis[u]] == 0break;
                    gap[dis[u] 
            = mint + 1]++;
                    u 
            = pre[u];
                    
            if (u == S) aug = inf;
                }
                
            return flow;
            }

            int main()
            {
                
            int n, m;
                
            while (scanf("%d%d"&n, &m) != EOF)
                {
                    init();
                    S 
            = 0;
                    T 
            = n + m + 1;
                    
            int sum = 0;
                    
            for (int i = 1; i <= n; ++i)
                    {
                        
            int x;
                        scanf(
            "%d"&x);
                        AddEdge(m 
            + i, T, x);
                    }
                    
            for (int i = 1; i <= m; ++i)
                    {
                        
            int a, b, c;
                        scanf(
            "%d%d%d"&a, &b, &c);
                        AddEdge(S, i, c);
                        AddEdge(i, m 
            + a, inf);
                        AddEdge(i, m 
            + b, inf);
                        sum 
            += c;
                    }
                    bfs();
                    sum 
            -= sap();
                    printf(
            "%d\n", sum);
                }
                
            return 0;
            }
            posted on 2011-10-15 22:10 LLawliet 閱讀(132) 評論(0)  編輯 收藏 引用 所屬分類: 網絡流
            狠狠色噜噜狠狠狠狠狠色综合久久| 久久夜色精品国产亚洲av| 77777亚洲午夜久久多人| 久久亚洲精品人成综合网| 亚洲成色999久久网站| 亚洲人成无码www久久久| 久久人人爽人人爽人人AV东京热| 亚洲综合婷婷久久| 99久久做夜夜爱天天做精品| 久久综合给久久狠狠97色| 久久久久亚洲AV无码去区首| 久久天堂AV综合合色蜜桃网 | 久久精品国产久精国产| 国内精品久久久久影院亚洲 | 久久国产影院| 国产产无码乱码精品久久鸭 | 久久香蕉综合色一综合色88| 欧美亚洲国产精品久久| 亚洲天堂久久精品| 日韩精品久久久肉伦网站| 久久99国产精品久久99小说| 人人狠狠综合久久亚洲88| 99久久免费国产特黄| 无码人妻精品一区二区三区久久久| 久久露脸国产精品| 精品久久久久久无码人妻热| 久久国产高清字幕中文| 久久精品亚洲精品国产色婷| 99久久精品免费看国产一区二区三区 | 亚洲另类欧美综合久久图片区| 色综合久久88色综合天天| 2021少妇久久久久久久久久| 久久精品国产亚洲av麻豆色欲 | 久久国产三级无码一区二区| 99久久免费国产精品热| 久久精品国产99国产精品澳门| 久久久一本精品99久久精品66| 亚洲国产精品无码久久一线| 亚洲综合日韩久久成人AV| 久久亚洲AV成人出白浆无码国产| 无码国内精品久久人妻蜜桃|