HDU1853Cyclic Tour(KM最小费用圈覆盖)
2015-08-31 18:54
423 查看
题意:已知城市分为几个不相交的环,每个城市只能属于一个环,一个环最少2个城市,求访问每一个城市一次的最小代价和,代价是城市之间的边。换言之,就是把所有城市访问一遍的最小代价。
解答:以城市之间的路为边,城市为顶点,建立二分图,KM匹配一下
解答:以城市之间的路为边,城市为顶点,建立二分图,KM匹配一下
#include<cstdio> #include<iostream> #include<algorithm> #include<cmath> #include<set> #include<map> #include<string> #include<cstring> #include<stack> #include<queue> #include<vector> #include<cstdlib> #define lson (rt<<1),L,M #define rson (rt<<1|1),M+1,R #define M ((L+R)>>1) #define cl(a,b) memset(a,b,sizeof(a)); #define LL long long #define P pair<int,int> #define X first #define Y second #define pb push_back #define fread(zcc) freopen(zcc,"r",stdin) #define fwrite(zcc) freopen(zcc,"w",stdout) using namespace std; const int maxn=205; const int inf=9999999; int w[maxn][maxn]; int linker[maxn],lx[maxn],ly[maxn],slack[maxn]; bool visx[maxn],visy[maxn]; int nx,ny; bool dfs(int x){ visx[x]=true; for(int i=0;i<ny;i++){ if(visy[i])continue; int tmp=lx[x]+ly[i]-w[x][i]; if(tmp==0){ visy[i]=true; if(linker[i]==-1||dfs(linker[i])){ linker[i]=x; return true; } }else if(slack[i]>tmp){ slack[i]=tmp; } } return false; } int km(){ cl(linker,-1); cl(ly,0); for(int i=0;i<nx;i++){ lx[i]=-inf; for(int j=0;j<ny;j++)if(w[i][j]>lx[i]){lx[i]=w[i][j];} } for(int x=0;x<nx;x++){ fill(slack,slack+ny+1,inf); while(true){ cl(visx,false); cl(visy,false); if(dfs(x))break; int d=inf; for(int i=0;i<ny;i++)if(!visy[i]&&slack[i]<d){ d=slack[i]; } for(int i=0;i<nx;i++)if(visx[i])lx[i]-=d; for(int i=0;i<ny;i++)if(visy[i])ly[i]+=d; else slack[i]-=d; } } int ans=0; cl(visx,false); for(int i=0;i<ny;i++)if(linker[i]!=-1){ ans+=w[linker[i]][i]; visx[linker[i]]=true; //printf("==%d\n",linker[i]); } for(int i=0;i<nx;i++)if(!visx[i])return 1;//不能全部访问到的 if(-ans>inf)return 1;//不合法的 return ans; } int main(){ int n,m; while(~scanf("%d%d",&n,&m)){ for(int i=0;i<n;i++){ for(int j=0;j<n;j++){ w[i][j]=-inf; } } for(int i=0;i<m;i++){ int x,y,v; scanf("%d%d%d",&x,&y,&v); x--;y--; if(-v>w[x][y])w[x][y]=-v;//筛选重边 } nx=ny=n; printf("%d\n",-km()); } return 0; }
相关文章推荐
- 百度ocr开放api调用python代码
- 九大排序算法总结
- 为什么监听不到开机广播action.BOOT_COMPLETED
- sublime text全程指南【转载】
- AWK 简明教程
- 递推DP UVA 590 Always on the run
- (4.2.16.1)Android之判断某个服务是否正在运行的方法
- 四个月,加油!
- Android 坐标与宽高研究getLeft() getTop() getRight()和getBottom()
- 移动web小问题解决方案
- mysql 赋予远程访问权限
- POJ1887 最长下降子序列
- POJ 3258:River Hopscotch 二分的好想法
- POJ 3258:River Hopscotch 二分的好想法
- 剑指offer 算法 (综合)
- 剑指offer 算法 (综合)
- git用法小结--建立远程仓库
- 南阳 dinner
- MySQL取整函数
- 今天第一次使用CSDN博客