HDU 3488 最小费用圈覆盖
2014-07-09 14:33
369 查看
题目:给定一幅图,让你找出旅游路径,路径包括一个或者多个环,每个城市只能属于一个环,每个环至少包含两个城市。
可以用网络流,也可以用KM算法求最小值,因为图中给的路径是有向的,且题目保证存在一个完备匹配。
可以用网络流,也可以用KM算法求最小值,因为图中给的路径是有向的,且题目保证存在一个完备匹配。
//其实在求最大 最小的时候只要用一个模板就行了,把边的权值去相反数即可得到另外一个.求结果的时候再去相反数即可 //邻接矩阵特别需要注意重边的问题,切记 #pragma comment(linker,"/STACK:102400000,102400000") #include <iostream> #include <string.h> #include <stdio.h> #include <algorithm> #include <vector> #include <string> #include <math.h> #include <queue> #include <stack> #include <map> #include <set> using namespace std; typedef long long ll; //记得必要的时候改成无符号 const int maxn=505; const int INF=1000000000; int n,nx,ny; int march[maxn],lx[maxn],ly[maxn],slack[maxn]; //lx,ly为顶标,nx,ny分别为x点集y点集的个数 int visx[maxn],visy[maxn],w[maxn][maxn]; int dfs(int x) { visx[x]=1; for(int y=1;y<=ny;y++) { if(visy[y]) continue; int t=lx[x]+ly[y]-w[x][y]; if(t==0) { visy[y]=1; if(march[y]==-1||dfs(march[y])) { march[y]=x; return 1; } } else if(slack[y]>t) //不在相等子图中slack 取最小的 slack[y]=t; } return 0; } int KM() { int i,j; memset(march,-1,sizeof(march)); memset(ly,0,sizeof(ly)); for(i=1;i<=nx;i++) //lx初始化为与它关联边中最大的 for(j=1,lx[i]=-INF;j<=ny;j++) if(w[i][j]>lx[i]) lx[i]=w[i][j]; for(int x=1;x<=nx;x++) { for(i=1;i<=ny;i++)slack[i]=INF; while(1) { memset(visx,0,sizeof(visx)); memset(visy,0,sizeof(visy)); if(dfs(x)) //若成功(找到了增广轨),则该点增广完成,进入下一个点的增广 break; //若失败(没有找到增广轨),则需要改变一些点的标号,使得图中可行边的数量增加。 //方法为:将所有在增广轨中(就是在增广过程中遍历到)的X方点的标号全部减去一个常数d, //所有在增广轨中的Y方点的标号全部加上一个常数d int d=INF; for(i=1;i<=ny;i++) if(!visy[i]&&d>slack[i]) d=slack[i]; for(i=1;i<=nx;i++) if(visx[i]) lx[i]-=d; for(i=1;i<=ny;i++) //修改顶标后,要把所有不在交错树中的Y顶点的slack值都减去d if(visy[i]) ly[i]+=d; else slack[i]-=d; } } int res=0; for(i=1;i<=ny;i++) if(march[i]>-1) res+=w[march[i]][i]; return res; } int main () { int T,i,j,m,x,y,z; scanf("%d",&T); while(T--){ scanf("%d%d",&n,&m); nx=ny=n; for(i=1;i<=n;i++)for(j=1;j<=n;j++)w[i][j]=-INF; for(i=1;i<=m;i++){ scanf("%d%d%d",&x,&y,&z); w[x][y]=max(w[x][y],-z); } printf("%d\n",-KM()); } return 0; }
相关文章推荐
- hdu 3488 Tour (有向环最小权值覆盖,费用流)
- hdu 4862 最小k路径覆盖 费用流
- HDU 3488 Tour(最小费用流:有向环最小权值覆盖)
- ★ HDU 4862 带费用的最小K路径覆盖
- (最小费用最大流模板)HDU 3488
- HDU 3488Tour(网络流之最小费用流)
- HDU 3488 Tour 用费用流解决完美匹配最小费用问题
- hdu 1853 Cyclic Tour (有向环最小权值覆盖,费用流)
- HDU 3488--Tour【最小费用最大流 && 有向环最小权值覆盖 && 经典】
- HDU 4862 Jump 最小k路径覆盖 费用流
- hdu 3488 Tour (最小权匹配 / 费用流)
- hdu 2215(凸包+最小圆覆盖)
- hdu 2215 (最小覆盖圆)(目前WA)
- HDU-1151 Air Raid 最小简单路径覆盖
- HDU 1151 Air Aaid 最小路径覆盖
- hdu National Treasures 二分图的最小点集覆盖
- HDU 4160 二分图最小点覆盖
- HDU 1151 Air Raid(最小路径覆盖)
- HDU 4160 Dolls 【最小路径覆盖】
- 最小路径覆盖&&http://acm.hdu.edu.cn/showproblem.php?pid=4160