您的位置:首页 > 其它

P2770 航空路线问题

2017-12-14 17:10 381 查看
#include <iostream>

#include <cstring>

#include <cstdio>

#include <string>

#include <vector>

#include <queue>

#include <map>

using namespace std;

const int N = 2150, oo = 0x3f3f3f3f;

const int Source = 2080, Sink = 2090;

struct Edge { int to, w, cap, rev; };

struct NetworkFlows

{

    int n, m, minCost, maxFlow;

    int dis
, prevV
, prevE
;

    bool used
, inq
;

    map<string, int> ID;

    map<int, string> CT;

    vector<Edge> G
;

    

    inline void addEdge(int u, int v, int c, int w)

    {

        int Gus = G[u].size(), Gvs = G[v].size();

        G[u].push_back((Edge){v, w, c, Gvs});

        G[v].push_back((Edge){u,-w, 0, Gus});

    }

    void Build()

    {

        string cityName, s1, s2;

        cin >>n >>m;

        for (int i = 1; i <= n; i++)

        {

            cin >>cityName;

            ID.insert(make_pair(cityName, i));

            CT.insert(make_pair(i, cityName));

            addEdge(i, i + 100, 1, -1);

        }

        addEdge(1, 1 + 100, 1, 0);

        addEdge(n, n + 100, 1, 0);

        for (int i = 1; i <= m; i++)

        {

            cin >>s1 >>s2;

            if (ID[s1] < ID[s2]) addEdge(ID[s1] + 100, ID[s2], 1, 0);

            else addEdge(ID[s2] + 100, ID[s1], 1, 0);

        }

        addEdge(Source, 1, 2, 0);

        addEdge(n + 100, Sink, 2, 0);

    }

    bool SPFA()

    {

        memset(dis, 0x3f, sizeof (dis));

        memset(inq, false, sizeof (inq));

        queue<int> q;

        q.push(Source), inq[Source] = true, dis[Source] = 0;

        

        int u, v;

        while (!q.empty())

        {

            u = q.front(), inq[u] = false, q.pop();

            for (int i = 0; i < (int)G[u].size(); i++)

            {

                v = G[u][i].to;

                if (dis[v] > dis[u] + G[u][i].w && G[u][i].cap > 0)

                {

                    dis[v] = dis[u] + G[u][i].w;

                    prevV[v] = u, prevE[v] = i;

                    if (!inq[v]) q.push(v), inq[v] = true;

                }

            }

        }

        return dis[Sink] < oo;

    }

    void MCMF()

    {

        minCost = 0, maxFlow = 0;

        while (SPFA())

        {

            int delta = oo;

            for (int i = Sink; i != Source; i = prevV[i])

                delta = min(delta, G[prevV[i]][prevE[i]].cap);

            minCost += delta * dis[Sink], maxFlow += delta;

            for (int i = Sink; i != Source; i = prevV[i])

            {

                Edge &E = G[prevV[i]][prevE[i]];

                E.cap -= delta, G[E.to][E.rev].cap += delta;

            }

        }

    }

    void DFS1(int u)

    {

        cout <<CT[u] <<endl;

        u = G[u][0].to;

        for (int i = 0, v; i < (int)G[u].size(); i++)

        {

            v = G[u][i].to;

            if (G[u][i].cap == 0 && v != Sink && v != u && !used[v])

            { DFS1(v), used[v] = true; return ; }

        }

    }

    vector<int> ansStack;

    void DFS2(int u)

    {

        ansStack.push_back(u);

        u = G[u][0].to;

        for (int i = 0, v; i < (int)G[u].size(); i++)

        {

            v = G[u][i].to;

            if (G[u][i].cap == 0 && v != Sink && v != u && !used[v])

            { DFS2(v), used[v] = true; return ; }

        }

    }

    void Work()

    {

        MCMF();

        minCost = -minCost;

        if (maxFlow == 0) cout <<"No Solution!" <<endl;

        else if (maxFlow == 1) cout <<2 <<endl <<CT[1] <<endl <<CT
<<endl <<CT[1] <<endl;

        else

        {

            cout <<minCost <<endl;

            DFS1(1);

            DFS2(1);

            while (ansStack.size())

            {

                cout <<CT[ansStack.back()] <<endl;

                ansStack.pop_back();

            }

        }

    }

} NF;

int main()

{

    ios::sync_with_stdio(false);

    NF.Build();

    NF.Work();

    return 0;

}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: