• <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
            Destroying The Graph
            Time Limit: 2000MSMemory Limit: 65536K
            Total Submissions: 4718Accepted: 1436Special Judge

            Description

            Alice and Bob play the following game. First, Alice draws some directed graph with N vertices and M arcs. After that Bob tries to destroy it. In a move he may take any vertex of the graph and remove either all arcs incoming into this vertex, or all arcs outgoing from this vertex. 
            Alice assigns two costs to each vertex: Wi+ and Wi-. If Bob removes all arcs incoming into the i-th vertex he pays Wi+ dollars to Alice, and if he removes outgoing arcs he pays Wi- dollars. 
            Find out what minimal sum Bob needs to remove all arcs from the graph.

            Input

            Input file describes the graph Alice has drawn. The first line of the input file contains N and M (1 <= N <= 100, 1 <= M <= 5000). The second line contains N integer numbers specifying Wi+. The third line defines Wi- in a similar way. All costs are positive and do not exceed 106 . Each of the following M lines contains two integers describing the corresponding arc of the graph. Graph may contain loops and parallel arcs.

            Output

            On the first line of the output file print W --- the minimal sum Bob must have to remove all arcs from the graph. On the second line print K --- the number of moves Bob needs to do it. After that print K lines that describe Bob's moves. Each line must first contain the number of the vertex and then '+' or '-' character, separated by one space. Character '+' means that Bob removes all arcs incoming into the specified vertex and '-' that Bob removes all arcs outgoing from the specified vertex.

            Sample Input

            3 6
            1 2 3
            4 2 1
            1 2
            1 1
            3 2
            1 2
            3 1
            2 3
            

            Sample Output

            5
            3
            1 +
            2 -
            2 +

            Source

            Northeastern Europe 2003, Northern Subregion



            一道典型的最小點權覆蓋問題,SAP速度很好看,之后需要搜索一下用過的點,輸出即可。
            代碼:
            #include <iostream>
            #include 
            <cstdio>
            #include 
            <cstring>
            #include 
            <cmath>
            #define N 10010
            #define M 20010
            #define inf 1 << 30
            #define eps 1 << 29
            using namespace std;

            int mark[N];
            int cnt, n, m, s, t;
            int head[N];
            int NN;

            struct edge
            {
                
            int v, next, w;
            } edge[M];

            void addedge(int u, int v, int w)
            {
                edge[cnt].v 
            = v;
                edge[cnt].w 
            = w;
                edge[cnt].next 
            = head[u];
                head[u] 
            = cnt++;
                edge[cnt].v 
            = u;
                edge[cnt].w 
            = 0;
                edge[cnt].next 
            = head[v];
                head[v] 
            = cnt++;
            }

            int sap()
            {
                
            int pre[N], cur[N], dis[N], gap[N];
                
            int flow = 0, aug = inf, u;
                
            bool flag;
                
            for (int i = 1; i <= NN; ++i)
                {
                    cur[i] 
            = head[i];
                    gap[i] 
            = dis[i] = 0;
                }
                gap[s] 
            = NN;
                u 
            = pre[s] = s;
                
            while (dis[s] < NN)
                {
                    flag 
            = 0;
                    
            for (int &= cur[u]; j != -1; j = edge[j].next)
                    {
                        
            int v = edge[j].v;
                        
            if (edge[j].w > 0 && dis[u] == dis[v] + 1)
                        {
                            flag 
            = 1;
                            
            if (edge[j].w < aug) aug = edge[j].w;
                            pre[v] 
            = u;
                            u 
            = v;
                            
            if (u == t)
                            {
                                flow 
            += aug;
                                
            while (u != s)
                                {
                                    u 
            = pre[u];
                                    edge[cur[u]].w 
            -= aug;
                                    edge[cur[u] 
            ^ 1].w += aug;
                                }
                                aug 
            = inf;
                            }
                            
            break;
                        }
                    }
                    
            if (flag)
                        
            continue;
                    
            int mindis = NN;
                    
            for (int j = head[u]; j != -1; j = edge[j].next)
                    {
                        
            int v = edge[j].v;
                        
            if (edge[j].w > 0 && dis[v] < mindis)
                        {
                            mindis 
            = dis[v];
                            cur[u] 
            = j;
                        }
                    }
                    
            if ((--gap[dis[u]]) == 0)
                        
            break;
                    gap[dis[u] 
            = mindis + 1]++;
                    u 
            = pre[u];
                }
                
            return flow;
            }

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

            void dfs(int x)      //不同于單純的SAP,加入了一個搜素點集元素的函數,通過head數組的記錄信息搜索。
            {
                mark[x] 
            = 1;
                
            for (int i = head[x]; i; i = edge[i].next)
                {
                    
            if (edge[i].w > 0 && !mark[edge[i].v]) dfs(edge[i].v);
                }
            }

            int main()
            {
                
            while (scanf("%d%d"&n, &m) != EOF)
                {
                    init();
                    
            int wp[101], wm[101], w, len = 1, ans[105];
                    s 
            = 0;
                    t 
            = 2 * n + 1;
                    NN 
            = 2 * n + 2;
                    
            for (int i = 1; i <= n; ++i)
                    {
                        scanf(
            "%d"&wp[i]);
                        addedge(i 
            + n, t, wp[i]);
                    }
                    
            for (int i = 1; i <= n; ++i)
                    {
                        scanf(
            "%d"&wm[i]);
                        addedge(s, i, wm[i]);
                    }
                    
            for (int i = 1; i <= m; ++i)
                    {
                        
            int x, y;
                        scanf(
            "%d%d"&x, &y);
                        addedge(x, y 
            + n, inf);
                    };
                    w 
            = sap();
                    dfs(s);
                    
            for (int i = 1; i <= n; ++i)
                    {
                        
            if (!mark[i]) ans[len++= i;
                        
            if (mark[i + n]) ans[len++= i + n;
                    }
                    len
            --;
                    printf(
            "%d\n%d\n", w, len);
                    
            for (int i = 1; i <= len; ++i)
                    {
                        
            if (ans[i] <=n) printf("%d -\n", ans[i]);
                        
            else printf("%d +\n", ans[i] - n);
                    }
                }
                
            return 0;
            }

            posted on 2011-10-15 22:09 LLawliet 閱讀(218) 評論(0)  編輯 收藏 引用 所屬分類: 網絡流
            国产精品久久毛片完整版| 久久久亚洲裙底偷窥综合| 久久久久国色AV免费观看| 久久WWW免费人成—看片| 欧美久久天天综合香蕉伊| 亚洲人成精品久久久久| 久久九九全国免费| 久久久久久国产a免费观看不卡| 国产精品成人久久久| 久久综合久久久| 久久久久久国产a免费观看黄色大片| 久久夜色精品国产欧美乱| 久久精品18| 69SEX久久精品国产麻豆| 午夜精品久久久久久影视777| 国产精品久久影院| 色青青草原桃花久久综合| 久久久青草久久久青草| 无码人妻久久一区二区三区| 久久99精品国产麻豆蜜芽| 2022年国产精品久久久久| 国产精品久久久久久五月尺| 久久精品国产精品亚洲| 国产精品久久久久9999| 亚洲AV成人无码久久精品老人| 久久免费观看视频| 久久香蕉综合色一综合色88| 久久精品国产清高在天天线| 一本色道久久99一综合| 中文字幕久久精品| 亚洲国产综合久久天堂 | 99久久99久久精品国产片果冻| 88久久精品无码一区二区毛片 | 国产 亚洲 欧美 另类 久久| 久久亚洲日韩看片无码| 伊人久久大香线蕉精品不卡| 婷婷久久综合九色综合绿巨人| 香蕉久久一区二区不卡无毒影院| 久久电影网2021| 亚洲国产成人久久综合碰碰动漫3d| 久久精品无码一区二区无码|