zoukankan      html  css  js  c++  java
  • 网络流小结

    第一个问题:
    费用流中。原图无负环的前提上。为什么增广时的最短路算法不会陷入负环。即为什么增广后的残图不会出现负环?

    事实上这是一个非常浅显的问题。但是我纠结了好长时间。233。

    首先如果残图会出现负环,则其出现负环的原因必定是增广后某些反向弧被增加的残图中。

    而增广路肯定是无环的。所以这些反向弧仅仅可能是负环的一部分。

    设这些反向弧组成的路径为P,P上各反向弧相应的边组成的路径为P',负环的还有一部分组成的路径为Q。

    而P成为负环的一部分的前提是P的权值和的绝对值大于Q的权值和。

    而上述前提的前提是 P' 的权值和大于Q的权值和。

    显然。上述前提与我们要寻找关于权值的最短增广路是相矛盾的。

    由于假设上述前提成立,那么我们拿Q来替换P'会得到一条关于权值的更短的增广路。

    所以,在原图无负环的前提上。增广后的残图中是不会出现负环的。


    ISAP

    #include <algorithm>
    #include <iostream>
    #include <cstring>
    #include <cstdlib>
    #include <cstdio>
    #include <queue>
    #include <cmath>
    #include <stack>
    #include <map>
    
    #pragma comment(linker, "/STACK:1024000000");
    #define EPS (1e-8)
    #define LL long long
    #define ULL unsigned long long
    #define _LL __int64
    #define INF 0x3f3f3f3f
    #define Mod 6000007
    
    using namespace std;
    
    const int EDGE = 6000000,POINT = 1010;
    
    struct E
    {
        int u,v,Max,next;
    }edge[EDGE];
    
    int head[POINT];
    
    int curr[POINT];
    
    int Top;
    
    void Link(int u,int v,int flow)
    {
        edge[Top].u = u;
        edge[Top].v = v;
        edge[Top].Max = flow;
        edge[Top].next = head[u];
        head[u] = Top++;
    }
    
    int dis[POINT],gap[POINT],pre[POINT];
    
    queue<int> q;
    
    void Updata_Dis(int S,int T,int n)
    {
        memset(dis,-1,sizeof(dis));
        memset(gap,0,sizeof(gap));
    
        dis[T] = 0;
        gap[0] = 1;
    
        q.push(T);
    
        int f;
    
        while(q.empty() == false)
        {
            f = q.front();
            q.pop();
    
            for(int p = head[f];p != -1;p = edge[p].next)
            {
                if(dis[edge[p].v] == -1)
                {
                    dis[edge[p].v] = dis[f] + 1;
                    gap[dis[f]+1]++;
                    q.push(edge[p].v);
                }
            }
        }
    }
    
    int ISAP(int S,int T,int n)
    {
        memcpy(curr,head,sizeof(curr));
    
        Updata_Dis(S,T,n);
    
        int flow = 0,u = pre[S] = S,p;
    
        while(dis[S] < n)
        {
            if(u == T)
            {
                int temp = INF,pos;
                for(p = S;p != T;p = edge[curr[p]].v)
                {
                    if(temp > edge[curr[p]].Max)
                    {
                        temp = edge[curr[p]].Max;
                        pos = p;
                    }
                }
    
                for(p = S;p != T;p = edge[curr[p]].v)
                {
                    edge[curr[p]].Max -= temp;
                    edge[curr[p]^1].Max += temp;
                }
    
                flow += temp;
                u = pos;
            }
    
            for(p = curr[u];p != -1;p = edge[p].next)
            {
                if(dis[edge[p].v]+1 == dis[u] && edge[p].Max)
                    break;
            }
    
            if(p != -1)
            {
                curr[u] = p;
                pre[edge[p].v] = u;
                u = edge[p].v;
            }
            else
            {
                if((--gap[dis[u]]) == 0)
                    break;
    
                int temp = n;
    
                for(p = head[u];p != -1;p = edge[p].next)
                {
                    if(temp > dis[edge[p].v] && edge[p].Max)
                    {
                        curr[u] = p;
                        temp = dis[edge[p].v];
                    }
                }
    
                dis[u] = temp+1;
                gap[dis[u]]++;
                u = pre[u];
            }
        }
        //printf("%d
    ",flow);
        return flow;
    }
    
    int L[410],R[410];
    
    int Map[410][410];
    
    bool mark[POINT];
    
    bool dfs(int s,int pre)
    {
        mark[s] = true;
        for(int p = head[s] ;p != -1; p = edge[p].next)
        {
            if(edge[p].v != pre && edge[p].Max)
            {
                if(mark[edge[p].v] == true || dfs(edge[p].v,s) == false)
                    return false;
            }
        }
    
        mark[s] = false;
        return true;
    }
    
    bool Judge(int n,int m)
    {
        memset(mark,false,sizeof(mark));
        for(int i = 1;i <= n; ++i)
        {
            if(dfs(i+1,-1) == false)
            {
                return false;
            }
        }
        return true;
    }
    
    int main()
    {
        int i,j,n,m,k;
    
        //freopen("1002.in","r",stdin);
        //freopen("data.out","w",stdout);
    
        while(scanf("%d %d %d",&n,&m,&k) != EOF)
        {
    
            memset(head,-1,sizeof(head));
            Top = 0;
    
            int ans = 0,sum = 0;
    
            int S = 1,T = 1+n+m+1;
    
            for(i = 1;i <= n; ++i)
            {
                scanf("%d",&L[i]);
                ans += L[i];
                Link(S,i+1,L[i]);
                Link(i+1,S,0);
            }
    
            for(i = 1;i <= m; ++i)
            {
                scanf("%d",&R[i]);
                sum += R[i];
                Link(n+i+1,T,R[i]);
                Link(T,n+i+1,0);
            }
    
            for(i = 1;i <= n; ++i)
            {
                for(j = 1;j <= m; ++j)
                {
                    Link(i+1,1+n+j,k);
                    Link(1+n+j,i+1,0);
                }
            }
    
            if(ans != sum || ans > n*m*k || ISAP(S,T,T) != ans)
            {
                printf("Impossible
    ");
            }
            else if(Judge(n,m) == false)
            {
                printf("Not Unique
    ");
            }
            else
            {
                for(i = 0;i < Top; i += 2)
                {
                    if(edge[i].u != S && edge[i].v != T)
                    {
                        Map[edge[i].u - 1][edge[i].v - n-1] = edge[i^1].Max;
                    }
                }
    
                printf("Unique
    ");
    
                for(i = 1;i <= n; ++i)
                {
                    for(j = 1;j <= m; ++j)
                    {
                        printf("%d",Map[i][j]);
                        if(j == m)
                            printf("
    ");
                        else
                            printf(" ");
                    }
                }
            }
        }
        return 0;
    }
    


  • 相关阅读:
    spring2.5 mvc使用注解upload上传文件
    从5点来分析搜索引擎算法
    搜索引擎算法研究专题六:HITS算法
    搜索引擎算法研究专题五:TFIDF详解
    搜索引擎算法研究专题二:HITS算法及其衍生算法分析
    搜索引擎算法研究专题一:基于页面分块的搜索引擎排序算法改进
    搜索引擎算法研究专题三:聚集索引与非聚集索引介绍
    Spring最佳实践9.1 集成邮件服务
    搜索引擎算法研究专题四:随机冲浪模型介绍
    搜索引擎算法研究专题七:Hilltop算法
  • 原文地址:https://www.cnblogs.com/mthoutai/p/6846941.html
Copyright © 2011-2022 走看看