UVA 1658Admiral

来源:互联网 发布:如何做seo推广 编辑:程序博客网 时间:2024/04/25 18:25

题目大意:给出v个点和e条边的有向带权图,求1~v俩条不相交的路径,使权和最小

解题思路:因为要求不相交,所以可以将2~v-1拆成俩个点i,ii,中间连一条容量1费用0的边,然后按照带权图的边将入度全连在i上,出度全连ii上,容量全部为1,费用为权值,将s与1连接,费用0,容量2,v与t连接,费用0,容量2,求最小费用流即可获得答案

#include <cstdio>#include <cstring>#include <queue>#include <iostream>#include <vector>using namespace std;#define INF 0x3f3f3f3f#define maxn 10000struct Edge {    int from, to, cost, cap, flow;    Edge(int from, int to, int cost, int cap, int flow):from(from), to(to), cost(cost), cap(cap), flow(flow){}};int m;vector<int> G[maxn];vector<Edge> edges;void addEdge(int x, int y, int co, int c) {    if(x != 0 && x != 1 && y < m+1) {        x += m+1;    }    edges.push_back(Edge(x, y, co, c, 0));    edges.push_back(Edge(y, x, -co, 0, 0));    int i = edges.size();    G[x].push_back(i-2);    G[y].push_back(i-1);}void init(int k) {    edges.clear();    for(int i = 0; i <= 2*m+1; i++)        G[i].clear();    while(k--) {        int x, y, cost;        cin >> x >> y >> cost;        addEdge(x, y, cost, 1);    }    addEdge(0, 1, 0, 2);    addEdge(m, m+1, 0, 2);    for(int i = 1; i <= m-1; i++) {        addEdge(i, i+m+1, 0, 1);    }}long long int BF(int s, int t) {    long long int re = 0;    int flow;    int flo[maxn];    int cos[maxn];    int pre[maxn];    while(1) {        queue<int> que;        int inq[maxn];        for(int i = 0; i <= 2*m+2; i++) {            cos[i] = INF;        }        cos[s] = 0;        memset(flo, 0, sizeof(flo));        memset(inq, 0, sizeof(inq));        flo[s] = INF;        pre[s] = 0;        que.push(s);        inq[s] = 1;        while(!que.empty()) {            int po = que.front();            que.pop();            inq[po] = 0;            for(int i = 0; i < G[po].size(); i++) {                Edge& ed = edges[G[po][i]];                if(cos[ed.to] > cos[po] + ed.cost && ed.cap > ed.flow) {                    cos[ed.to] = cos[po] + ed.cost;                    pre[ed.to] = G[po][i];                    flo[ed.to] = min(ed.cap - ed.flow, flo[po]);                    if(!inq[ed.to]) {                        que.push(ed.to);                        inq[ed.to] = 1;                    }                }            }        }        if(cos[t] == INF) {            return re;        }        flow += flo[t];        re += (long long int)flo[t] * (long long int)cos[t];        for(int i = t; i != s; i = edges[pre[i]].from) {            edges[pre[i]].flow += flo[t];            edges[pre[i]^1].flow -= flo[t];        }    }}int main() {    int k;    while(cin >> m >> k && m) {        init(k);        cout << BF(0, m+1) << endl;    }    return 0;}
原创粉丝点击