• uva 1349 Optimal Bus Route Design(拆点,费用流)


    题目链接

    题意:给出(n(1 leq n leq 100))个点,每个点与其他一些点相连,边上有权值,现在需要选一些边将所有点包括在一个环内(有且仅有一个环包含每个点,可以有多个环),使得所选边权值之和最小。

    题解:对于每个点存在唯一环包括他,等价于每个点存在唯一后继,对于唯一性,可以想到二分图,将原来每个点拆为两个点,然后加个源和汇s,t,在将边权转化为费用跑费用流就行了。

    #include<iostream>
    #include<cstdio>
    #include<algorithm>
    #include<cstring>
    #include<vector>
    #include<queue>
    #include<stack>
    using namespace std;
    #define rep(i,a,n) for (int i=a;i<n;i++)
    #define per(i,a,n) for (int i=n-1;i>=a;i--)
    #define pb push_back
    #define fi first
    #define se second
    typedef vector<int> VI;
    typedef long long ll;
    typedef pair<int,int> PII;
    const int inf=0x3fffffff;
    const ll mod=1000000007;
    const int MAXN =200+10;
    const int MAXM = 21000;
    const int INF = 1e9;
    struct Edge
    {
        int to,next,cap,flow,cost;
    }edge[MAXM];
    int head[MAXN],tol;
    int pre[MAXN],dis[MAXN];
    bool vis[MAXN];
    int N;//节点总个数,节点编号从0~N-1
    
    void addedge(int u,int v,int cap,int cost)
    {
        edge[tol].to = v;edge[tol].cap = cap;edge[tol].cost = cost;edge[tol].flow = 0;
        edge[tol].next = head[u];head[u] = tol++;
        edge[tol].to = u;edge[tol].cap = 0;edge[tol].cost = -cost;edge[tol].flow = 0;
        edge[tol].next = head[v];head[v] = tol++;
    }
    
    
    bool spfa(int s,int t)
    {
        queue<int> q;
        for(int i = 0;i < N;i++)
        {
            dis[i] = INF;
            vis[i] = false;
            pre[i] = -1;
        }
        dis[s] = 0;
        vis[s] = true;
        q.push(s);
        while(!q.empty())
        {
            int u = q.front();
            q.pop();
            vis[u] = false;
            for(int i = head[u]; i != -1;i = edge[i].next)
            {
                int v = edge[i].to;
                if(edge[i].cap > edge[i].flow &&
                   dis[v] > dis[u] + edge[i].cost )
                {
                    dis[v] = dis[u] + edge[i].cost;
                    pre[v] = i;
                    if(!vis[v])
                    {
                        vis[v] = true;
                        q.push(v);
                    }
                }
            }
        }
        if(pre[t] == -1)return false;
        else return true;
    }
    //返回的是最大流,cost存的是最小费用
    int minCostMaxflow(int s,int t,int &cost)
    {
        int flow = 0;
        cost = 0;
        while(spfa(s,t))
        {
            int Min = INF;
            for(int i = pre[t];i != -1;i = pre[edge[i^1].to])
            {
                if(Min > edge[i].cap - edge[i].flow)
                    Min = edge[i].cap - edge[i].flow;
            }
            for(int i = pre[t];i != -1;i = pre[edge[i^1].to])
            {
                edge[i].flow += Min;
                edge[i^1].flow -= Min;
                cost += edge[i].cost * Min;
            }
            flow += Min;
        }
        return flow;
    }
    
    
    int main()
    {
        int n;
        while(~scanf("%d",&n)&&n)
        {
            int st=0,ed=2*n+1;
            N=ed+1;
            tol=0;
            rep(i,0,ed+1) head[i]=-1;
            rep(i,1,n+1)
            {
                int p;
                while(~scanf("%d",&p))
                {
                    if(!p) break;
                    int w;
                    scanf("%d",&w);
                    addedge(i,n+p,1,w);
                }
            }
            rep(i,1,n+1) addedge(st,i,1,0),addedge(n+i,ed,1,0);
            int cost=0;
            int t=minCostMaxflow(st,ed,cost);
            if(t<n) puts("N");
            else printf("%d
    ",cost);
        }
        return 0;
    }
    
  • 相关阅读:
    强化学习的基本迭代方法
    基于文本描述的事务聚类
    学习强化学习之前需要掌握的3种技能
    其它 华硕 ASAU S4100U 系统安装 win10安装 重装系统 Invalid Partition Table 解决
    数据分析 一些基本的知识
    Python 取样式的内容 合并多个文件的样式 自定义样式
    电商 Python 生成补单公司需要的评论格式3
    SpringBlade 本地图片上传 生成缩略图
    SQL Server 字符串截取
    SpringBlade 本地图片上传
  • 原文地址:https://www.cnblogs.com/tarjan/p/7350804.html
Copyright © 2020-2023  润新知