Tour

来源:互联网 发布:淘宝店铺如何关闭 编辑:程序博客网 时间:2024/05/16 04:18

点击打开链接

题意:在一个王国有N个城市,M条路。选择N条路,构成一个环路。求出最小距离。

解析:构图,最小费用最大流。将源点和终点至个点花费记作0,然后将所有路径流量记作1或同一值。

#include<iostream>#include<cstdio>#include<cstring>#include<queue>using namespace std;const int maxn = 10000;const int maxm = 100000;const int INF = 0xfffffff;struct Edge{int to, next, cap, flow, cost;}edge[ maxm ];int head[ maxn ], tol;int pre[ maxn ], dis[ maxn ];bool vis[ maxn ];int N;void init( int n ){N = n;tol = 0;memset( head, -1, sizeof( head ) );}void addedge( int u, int v, int cap, int cost ){edge[ tol ].to = v;edge[ tol ].cap = cap;edge[ tol ].cost = cost;edge[ tol ].flow = 0;edge[ tol ].next = head[ u ];head[ u ] = tol++;edge[ tol ].to = u;edge[ tol ].cap = 0;edge[ tol ].cost = -cost;edge[ tol ].flow = 0;edge[ tol ].next = head[ v ];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;elsereturn true;}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 cost;}int main(){int Case;int n, m;scanf( "%d", &Case );while( Case-- ){scanf( "%d%d", &n, &m );int N = 2 * n + 2;int start = 0, end = 2 * n + 1;init( N );for( int i = 1; i <= n; ++ i ){addedge( 0, i, 1, 0 );}for( int i = 1; i <= n; ++i ){addedge( n + i, end, 1, 0 );}int x, y, value;for( int i = 0; i < m; ++i ){scanf( "%d%d%d", &x, &y, &value );addedge( x, n + y, 1, value );}int cost;int ans = minCostMaxflow( start, end, cost );cout << ans << endl;}return 0;}


0 0
原创粉丝点击