POJ

来源:互联网 发布:双色球全国关注数据 编辑:程序博客网 时间:2024/06/11 00:55

就是从1走到n然后再走回来,一条边只能走一次,要求路径最短。

// MCMF 最小费用最大流#include <cstdio>#include <vector>#include <string>#include <string.h>#include <queue>#define MAX 1000 + 5#define INF 0x3fffffffusing namespace std;struct Edge {    int from, to, cap, flow, cost;    Edge( int u, int v, int ca, int f, int co ) : from(u),to(v),cap(ca),flow(f),cost(co){};};int n,m,s,t;vector<Edge> edges;vector<int> G[MAX];int inq[MAX];//是否在队列中int d[MAX];//距离int p[MAX];//上一条弧int a[MAX];//可改进量void init( int n ) {//初始化    for( int i = 0; i < n; i++ )        G[i].clear();    edges.clear();}void addEdge( int from, int to, int cap, int cost ) { //加边    edges.push_back( Edge( from, to, cap, 0, cost ) );    edges.push_back( Edge( to, from, 0, 0, -cost ) );    int m = edges.size();    G[from].push_back( m - 2 );    G[to].push_back( m - 1 );}bool SPFA( int s, int t, int &flow, int &cost ) { //寻找最小费用的增广路,使用引用同时修改原flow,cost    fill( d, d + MAX, INF );    memset( inq, 0, sizeof( inq ) );    // 源点入队部分    d[s] = 0;    inq[s] = 1;    p[s] = 0;    a[s] = INF;    queue<int> q;    q.push( s );    while( !q.empty () ) {        int u = q.front();        q.pop();        inq[u]--;        for( int i = 0; i < G[u].size(); i++ ) {            Edge& e = edges[G[u][i]];            if( e.cap > e.flow && d[e.to] > d[u] + e.cost ) { //满足可增广且可变短                d[e.to] = d[u] + e.cost;                p[e.to] = G[u][i];                a[e.to] = min( a[u], e.cap - e.flow );                if( !inq[e.to] ) {                    inq[e.to]++;                    q.push(e.to);                }            }        }    }    if( d[t] == INF ) return false; //汇点不可达则退出    flow += a[t];    cost += d[t] * a[t];    int u = t;    while( u != s ) { //更新正向边和反向边        edges[p[u]].flow += a[t];        edges[p[u] ^ 1].flow -= a[t];        u = edges[p[u]].from;    }    return true;}int MincotMaxflow( int s, int t, int cnt ) {    int flow = 0, cost = 0;    //while( SPFA( s, t, flow, cost ) );    while( cnt > 0 ) {        SPFA( s, t, flow, cost );        cnt--;    }    return cost;}int main() {    int a, b, c;    while( ~scanf( "%d%d", &n, &m ) ) {        init( n );        for( int i = 0; i < m; i++ ) {            scanf( "%d%d%d", &a, &b, &c );            addEdge( a - 1, b - 1, 1, c );            addEdge( b - 1, a - 1, 1, c );        }        printf( "%d\n", MincotMaxflow( 0, n - 1, 2 ) );    }    return 0;}