HDU 3488 — Tour 费用流/KM算法
来源:互联网 发布:ubuntu yum 编辑:程序博客网 时间:2024/05/16 06:49
原题:http://acm.hdu.edu.cn/showproblem.php?pid=3488
题意:
有n个点,m条有向带权边;
求一些环,使得每个点属于且仅属于一个环;
问环边的权值和的最小值;
思路:
拆点,建图,跑一个费用流;
源点到节点,流量为1,花费为0(s, i, 0, 1);
节点到节点,流量为1, 花费为边权值(u, v+n, cos, 1);
节点到汇点,流量为1,花费为0(i+n, t, 0, 1);
#include <cstdio>#include <cstring>#include <queue>#include <vector>#define oo 0x3f3f3f3f#define maxn 410using namespace std;struct Edge { int u, v, c, f; Edge( int u, int v, int c, int f ):u(u),v(v),c(c),f(f){}};struct Mcmf { int n, src, dst; vector<Edge> edge; vector<int> g[maxn]; int dis[maxn], ext[maxn], pth[maxn]; void init( int nn, int s, int d ){ n = nn; src = s; dst = d; for( int i=1; i<=n; i++ ) g[i].clear(); edge.clear(); } void add_edge( int u, int v, int c, int f ){ g[u].push_back( edge.size() ); edge.push_back( Edge(u,v,c,f) ); g[v].push_back( edge.size() ); edge.push_back( Edge(v,u,-c,0) ); } bool spfa( int &flow, int &cost ) { queue<int> qu; memset( dis, 0x3f, sizeof(dis) ); qu.push( src ); dis[src] = 0; ext[src] = true; pth[src] = -1; while( !qu.empty() ) { int u = qu.front(); qu.pop(); ext[u] = false; for( int t=0; t<g[u].size(); t++) { Edge &e = edge[g[u][t]]; if( e.f && dis[e.v]>dis[e.u]+e.c ) { dis[e.v] = dis[e.u]+e.c; pth[e.v] = g[u][t]; if( !ext[e.v] ) { ext[e.v] = true; qu.push( e.v ); } } } } if( dis[dst]==oo ) return false; int flw = oo; for( int eid=pth[dst]; eid!=-1; eid=pth[edge[eid].u] ) flw = min( flw, edge[eid].f ); for( int eid=pth[dst]; eid!=-1; eid=pth[edge[eid].u] ) { edge[eid].f -= flw; edge[eid^1].f += flw; } flow += flw; cost += flw*dis[dst]; return true; } void mcmf( int &flow, int &cost ) { flow = cost = 0; while( spfa(flow,cost) ); }};int n, m;Mcmf M;int main() { int cas; scanf( "%d", &cas); while(cas--) { scanf( "%d%d", &n, &m); int s = 0, t = n*2+1; M.init(t+1, s, t); for(int i = 1;i<=m;i++) {int u, v, cos; scanf("%d%d%d", &u, &v, &cos); M.add_edge(u, v+n, cos, 1); } for(int i = 1;i<=n;i++) { M.add_edge(M.src, i, 0, 1); M.add_edge(i+n, M.dst, 0, 1); } int flow, cost; M.mcmf(flow, cost); printf("%d\n", cost); } return 0;}
0 0
- HDU 3488 — Tour 费用流/KM算法
- HDU 3488 Tour (最小费用流 或 KM)
- hdoj 3488 Tour 【最小费用最大流】【KM算法】
- HDU 1853 Cyclic Tour && HDU 3488Tour KM算法
- hdu1853 Cyclic Tour (KM算法求最小费用流)
- hdu 3488 Tour (KM)
- tour hdu 3488 KM
- hdu 3488 Tour KM
- HDU 3488 Tour [裂点+KM或最小费用最大流]
- HDU 3488 Tour 费用流
- hdu 3488 Tour(最小费用流orKM算法)
- HDU 1853 Cyclic Tour && HDU 3488Tour 最小费用流
- hdu 3488 Tour(费用流,去重边)
- hdu 3488 Tour【最小费用最大流】
- HDU 1853 Cyclic Tour KM算法
- hdu 3488 Tour【KM】同hdu 1853
- HDU 1533 Going Home【最小费用流|KM算法】
- HDU 3435 KM算法或者最小费用最大流
- Oracle学习(4):分组函数
- 线程池
- 使用R进行时间序列分解
- 【C++】基于特征向量的KNN分类算法
- Windows程序设计(消息机制)
- HDU 3488 — Tour 费用流/KM算法
- 疯狂Java学习笔记(59)-----------50道Java线程面试题
- Linux Shell脚本攻略(1.7)
- 3.1-2
- 现在
- ClassLoader 详解及用途
- svn可以在本地使用的
- 3.1-3
- 链地址法+动态开辟内存 hash