• <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)  編輯 收藏 引用 所屬分類: 網絡流
            色欲久久久天天天综合网精品| 精品国产乱码久久久久久1区2区| 久久99久久成人免费播放| 欧美亚洲日本久久精品| 久久人妻无码中文字幕| 久久久av波多野一区二区| 久久久WWW成人免费精品| 九九精品99久久久香蕉| 久久青青草原精品国产软件| 天堂久久天堂AV色综合| 性高湖久久久久久久久AAAAA | 国产精品久久久久久久久软件| 久久国产精品一国产精品金尊| 久久一本综合| 久久99免费视频| 97精品依人久久久大香线蕉97| 国产精品99久久久久久宅男| 婷婷伊人久久大香线蕉AV | 精品久久久久久无码专区| 亚洲精品乱码久久久久久蜜桃| 亚洲国产精品久久66| 青青草原精品99久久精品66| 久久久久久亚洲精品影院| 精品久久综合1区2区3区激情| 国产精品久久免费| AV无码久久久久不卡网站下载 | 亚洲成色999久久网站| 久久亚洲精品人成综合网| 色婷婷综合久久久久中文 | 精品久久久久成人码免费动漫| 久久久精品人妻无码专区不卡| 99久久国产综合精品网成人影院| 久久亚洲AV成人出白浆无码国产| 日本人妻丰满熟妇久久久久久| 久久精品国产免费观看三人同眠| 99久久精品免费看国产一区二区三区 | 久久精品国产久精国产思思| 久久久久婷婷| 内射无码专区久久亚洲| 久久久这里只有精品加勒比| 亚洲精品无码专区久久久|