• <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 閱讀(220) 評論(0)  編輯 收藏 引用 所屬分類: 網絡流
            久久久精品2019免费观看| 国产精品99久久久久久董美香| 国内精品久久久久影院网站| 99久久免费国产精精品| 精品久久久久香蕉网| 久久成人18免费网站| 久久受www免费人成_看片中文| 亚洲伊人久久大香线蕉综合图片| 久久成人国产精品| 国产精品美女久久久久av爽| 国产精品久久久久久五月尺| 新狼窝色AV性久久久久久| 久久精品免费观看| 久久九九兔免费精品6| 一本大道加勒比久久综合| 久久无码AV中文出轨人妻| 久久r热这里有精品视频| 久久精品国产2020| 久久夜色撩人精品国产| 久久精品人人做人人爽电影| 久久精品一本到99热免费| 激情五月综合综合久久69| 久久婷婷成人综合色综合| 久久无码精品一区二区三区| 72种姿势欧美久久久久大黄蕉| 一日本道伊人久久综合影| 26uuu久久五月天| 久久99精品国产| 99久久精品国产麻豆| 亚洲国产精品无码久久久秋霞2| 亚洲日韩欧美一区久久久久我| 久久国产成人午夜AV影院| 国产福利电影一区二区三区久久久久成人精品综合 | 久久亚洲精品无码VA大香大香| 久久久久免费精品国产| 久久免费的精品国产V∧| 久久久久亚洲AV无码观看| 久久久久人妻一区精品果冻| 国产高清国内精品福利99久久| 色综合久久88色综合天天| 久久99精品国产|