• Aizu 2304 Reverse Roads 费用流


    Reverse Roads

    Time Limit: 1 Sec  

    Memory Limit: 256 MB

    题目连接

    http://acm.hust.edu.cn/vjudge/contest/view.action?cid=93265#problem/E

    Description

    ICP city has an express company whose trucks run from the crossing S to the crossing T. The president of the company is feeling upset because all the roads in the city are one-way, and are severely congested. So, he planned to improve the maximum flow (edge disjoint paths) from the crossing S to the crossing T by reversing the traffic direction on some of the roads.

    Your task is writing a program to calculate the maximized flow from S to T by reversing some roads, and the list of the reversed roads.

    Input

    The first line of a data set contains two integers N (2 leq N leq 300) and M (0 leq M leq { m min} (1\,000, N(N-1)/2)). N is the number of crossings in the city and M is the number of roads.

    The following M lines describe one-way roads in the city. The i-th line (1-based) contains two integers X_i and Y_i (1 leq X_i, Y_i leq N,X_i eq Y_i). X_i is the ID number (1-based) of the starting point of the i-th road and Y_i is that of the terminal point. The last line contains two integers S and T (1 leq S, T leq NS eq T1-based).

    The capacity of each road is 1. You can assume that i eq j implies either X_i eq X_j or Y_i eq Y_j, and either X_i eq Y_j or X_j eq Y_i.

    Output

    In the first line, print the maximized flow by reversing some roads. In the second line, print the number R of the reversed roads. In each of the following R lines, print the ID number (1-based) of a reversed road. You may not print the same ID number more than once.

    If there are multiple answers which would give us the same flow capacity, you can print any of them.

    Sample Input

    2 1
    2 1
    2 1

    Sample Output

    1
    0

    HINT

    题意

    给你一个图,然后图的边可以反转,反转的代价为1,问你保证最大流的情况下,使得反转的边最少

    并且把反转的边输出出来

    题解:

    裸的费用流,特别裸……

    代码:

    //qscqesze
    #include <cstdio>
    #include <cmath>
    #include <cstring>
    #include <ctime>
    #include <iostream>
    #include <algorithm>
    #include <set>
    #include <bitset>
    #include <vector>
    #include <sstream>
    #include <queue>
    #include <typeinfo>
    #include <fstream>
    #include <map>
    #include <stack>
    typedef long long ll;
    using namespace std;
    //freopen("D.in","r",stdin);
    //freopen("D.out","w",stdout);
    #define sspeed ios_base::sync_with_stdio(0);cin.tie(0)
    #define maxn 200500
    #define mod 1001
    #define eps 1e-9
    #define pi 3.1415926
    int Num;
    //const int inf=0x7fffffff;
    const ll inf=999999999;
    inline ll read()
    {
        ll x=0,f=1;char ch=getchar();
        while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
        while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();}
        return x*f;
    }
    //*************************************************************************************
    const int MAXN = 1000;
    const int MAXM = 150000;
    const int INF = 0x3f3f3f3f;
    struct Edge
    {
        int to, next, cap, flow, cost, id;
        int x, y;
    } edge[MAXM],HH[MAXN],MM[MAXN];
    int head[MAXN],tol;
    int pre[MAXN],dis[MAXN];
    bool vis[MAXN];
    int N, M;
    char map[MAXN][MAXN];
    void init()
    {
        N = MAXN;
        tol = 0;
        memset(head, -1, sizeof(head));
    }
    void addedge(int u, int v, int cap, int cost,int id)//左端点,右端点,容量,花费, 编号
    {
        edge[tol]. to = v;
        edge[tol]. cap = cap;
        edge[tol]. cost = cost;
        edge[tol]. flow = 0;
        edge[tol]. next = head[u];
        edge[tol].id = id;
        head[u] = tol++;
        edge[tol]. to = u;
        edge[tol]. cap = 0;
        edge[tol]. cost = -cost;
        edge[tol]. flow = 0;
        edge[tol]. next = head[v];
        edge[tol].id = id;
        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存的是最小费用
    vector<int> ans;
    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;
    }
    
    vector<int> Q;
    int main()
    {
        init();
        int n=read(),m=read();
        for(int i=0;i<m;i++)
        {
            int x=read(),y=read();
            addedge(x,y,1,0,i+1);
            addedge(y,x,1,1,i+1);
        }
        int s=read(),t=read();
        int ans1 = 0,ans2 = 0;
        ans1 = minCostMaxflow(s,t,ans2);
    
        for(int i=1;i<=n;i++)
        {
            for(int j = head[i]; j != -1; j = edge[j]. next)
            {
                if(edge[j].flow == 1)
                {
                    if(edge[j].cost)
                    {
                        Q.push_back(edge[j].id);
                    }
                }
            }
        }
    
    
        printf("%d
    %d
    ",ans1,ans2);
        for(int i=0;i<Q.size();i++)
            printf("%d
    ",Q[i]);
    }
  • 相关阅读:
    订单超时30分钟自动取消
    获取网络时间
    aspose.words通过域导出word文件
    Excel导入时,解析日期类型单元格的办法。
    ALTER TABLE 报1062
    mysql快速生成测试数据
    GP 源码编译安装
    Kafka 集群群起/关闭脚本
    Zookeeper 常用命令
    OGG 同步无主键表且目标表多一个隐藏字段
  • 原文地址:https://www.cnblogs.com/qscqesze/p/4851565.html
Copyright © 2020-2023  润新知