zoukankan      html  css  js  c++  java
  • 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]);
    }
  • 相关阅读:
    Python运算符及逻辑运算
    Python编码、流程控制、格式化输出
    Docker私有仓库Harbor部署与使用
    react
    理事会
    关于elementui form表单过长,看不到未填项
    js
    vue 父子传值
    养生
    html知识点
  • 原文地址:https://www.cnblogs.com/qscqesze/p/4851565.html
Copyright © 2011-2022 走看看