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]);
    }
  • 相关阅读:
    ES6之Promise封装ajax()
    ECMAScript 6 入门之 展开运算符(...)
    函数篇:Callback----回调函数
    Vue-cli组件中写一个节流函数
    使用vant中的地址编辑组件
    js中substr()、substring()、chatAt()的区别
    npm使用国内淘宝镜像的方法
    js数组
    ECMAScript版本
    匿名函数的调用
  • 原文地址:https://www.cnblogs.com/qscqesze/p/4851565.html
Copyright © 2011-2022 走看看