• <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)  編輯 收藏 引用 所屬分類: 網絡流
            青青热久久综合网伊人| 国产A级毛片久久久精品毛片| 免费无码国产欧美久久18| 国产精品成人久久久| 久久人人爽人人爽人人爽| 国产精品免费看久久久| 久久99国产一区二区三区| 久久99国产精品久久99小说| 久久A级毛片免费观看| 久久精品国产99久久丝袜| 久久久国产打桩机| 一本久久a久久精品综合夜夜| 一级做a爰片久久毛片免费陪| 新狼窝色AV性久久久久久| 久久精品无码一区二区日韩AV| 久久午夜免费视频| 欧美激情精品久久久久| 日韩人妻无码精品久久免费一| 国产精品午夜久久| 久久99国产亚洲高清观看首页| 一本久久免费视频| 久久国产福利免费| 久久96国产精品久久久| 亚洲欧美日韩中文久久| 久久久久久国产精品无码下载 | 精品久久无码中文字幕| 久久涩综合| 久久精品免费大片国产大片| 亚洲国产成人久久精品动漫| www性久久久com| 精品无码久久久久久尤物| 伊人久久大香线蕉成人| 久久免费视频1| 一本久久免费视频| 思思久久好好热精品国产| 久久久青草青青国产亚洲免观| 国内精品免费久久影院| 久久免费视频一区| 精品久久久久国产免费| 久久性生大片免费观看性| 人妻少妇精品久久|