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



            一道典型的最小點(diǎn)權(quán)覆蓋問(wèn)題,SAP速度很好看,之后需要搜索一下用過(guò)的點(diǎn),輸出即可。
            代碼:
            #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,加入了一個(gè)搜素點(diǎn)集元素的函數(shù),通過(guò)head數(shù)組的記錄信息搜索。
            {
                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) 評(píng)論(0)  編輯 收藏 引用 所屬分類(lèi): 網(wǎng)絡(luò)流
            青青青国产精品国产精品久久久久| 69SEX久久精品国产麻豆| 99久久精品国产一区二区三区| 国产99精品久久| 青草影院天堂男人久久| 香蕉99久久国产综合精品宅男自 | 综合网日日天干夜夜久久| 久久人人爽人人人人爽AV| 色狠狠久久AV五月综合| 久久伊人精品青青草原高清| 亚洲国产成人精品久久久国产成人一区二区三区综| 亚洲国产精品无码久久青草| 国产成人无码精品久久久性色| 97热久久免费频精品99| 伊人伊成久久人综合网777| 国产精品久久一区二区三区 | 久久A级毛片免费观看| 久久se精品一区二区影院| 亚洲欧美成人综合久久久| 久久精品中文字幕一区| 2021少妇久久久久久久久久| 99精品久久精品一区二区| 久久久久亚洲AV成人网人人软件| 久久久久国产精品熟女影院 | 亚洲а∨天堂久久精品9966| AAA级久久久精品无码区| 无码国内精品久久人妻蜜桃 | 久久91综合国产91久久精品| 久久精品一本到99热免费| 人妻无码精品久久亚瑟影视| 国产成人无码精品久久久久免费 | 久久久WWW成人| 国产午夜福利精品久久| 久久精品国产99国产电影网 | 人妻精品久久久久中文字幕69 | 无码国内精品久久人妻蜜桃| 中文字幕无码av激情不卡久久| 久久久久18| 久久亚洲高清综合| 久久久精品久久久久影院| 国产精品久久久久久五月尺|