hdu 3488 Tour (最小权匹配 / 费用流)
来源:互联网 发布:环球人物和看天下知乎 编辑:程序博客网 时间:2024/05/22 03:14
题意:有N个城市,M条街道(连接两点的距离),每条街道是单向的,现在要你设计多条路线覆盖所有的点,每条路线都是一个环,并且每个点仅能被一条路线覆盖且只经过一次(终始点除外),
分析:因为是有向圈,所以每个点的入度和出度应该都是1,故将一个点拆成两个点,入度点和出度点,然后用最佳匹配即可!(因为最佳匹配是求最大值,故我们把边权设为负值即可!)
注意:这题有重边,题目太不道德了,有重边都不说,还要猜的啊!有些题没说有重边就没重边,有些题没说有重边但是它就是有重边!无敌了都!
KM_match :
#include <iostream>#include <stdio.h>#include <string.h>using namespace std;const int inf=10000000;const int N=205;int m[N][N]; //邻接矩阵int lx[N],ly[N]; //顶点标号int fx[N],fy[N];//是否已经搜索过,S为寻找从i出发的增广轨时访问的x中的点的集合,T为访问的y中的点的集合。int match[N];int n;int dfs(int k) //从x[k]寻找增广路{ fx[k]=1; for(int i=1; i<=n; i++) { if(!fy[i]&& lx[k]+ly[i]==m[k][i])//相等子图 { fy[i]=1; if(match[i]==-1||dfs(match[i])) { match[i]=k; return 1; } } } return 0;}int KM_match() //求解最小权匹配{ int Min; for(int i=1; i<=n; i++) { lx[i]=-1;//x中顶点i的编号为与i关联的Y中边的最大权重 for(int j=1; j<=n; j++) if(lx[i]<m[i][j]) lx[i]=m[i][j];//初始化x的顶点标号 } memset(ly,0,sizeof(ly));//初始化y的顶点标号 memset(match,-1,sizeof(match)); for(int k=1; k<=n; k++) { while(1) { memset(fx,0,sizeof(fx)); memset(fy,0,sizeof(fy)); if(dfs(k)) break; Min=inf; for(int i=1; i<=n; i++) if(fx[i]) //x在交错树中 for(int j=1; j<=n; j++) if(!fy[j])//y不在交错树中,扩大子图 Min=min(Min,lx[i]+ly[j]-m[i][j]); //若匹配不成功,则修改顶点标号,找到d的值 for(int i = 1 ; i <= n ;i++) if(fx[i]) lx[i] -= Min ; for(int i = 1 ; i <= n ;i++) if(fy[i]) ly[i] += Min ; } } int sum=0; for(int i=1; i<=n; i++) sum+=m[match[i]][i]; return -sum;}int main(){ int t; cin>>t; while(t--) { int M,ans; cin>>n>>M; for(int i=0; i<=n; i++) for(int j=0; j<=n; j++) m[i][j]=-inf;//即将边的权值取反 while(M--) { int u,v,w; cin>>u>>v>>w; if(m[u][v]<-w)//WA的地方,注意呀!!! m[u][v]=-w; } ans=KM_match(); printf("%d\n",ans); } return 0;}
最小费用最大流 :
也是拆点, (s,i,1,0) ,(i+n,t,1,0) ,(a,b+n,1,cost) ;
#include<cstdio>#include<cstring>#include<map>#include<vector>#include<cmath>#include<cstdlib>#include<stack>#include<queue>#include <iomanip>#include<iostream>#include<algorithm>using namespace std ;const int N=2500 ;const int inf=1<<30;struct node{ int u,v,c,cost,next;} edge[N*100] ;int dist[N],pre[N],head[N],vist[N];int g[N][N],top;void add(int u ,int v ,int c,int cost){ edge[top].u=u;edge[top].v=v;edge[top].c=c;edge[top].cost=cost;edge[top].next=head[u];head[u]=top++; edge[top].u=v;edge[top].v=u;edge[top].c=0;edge[top].cost=-cost;edge[top].next=head[v];head[v]=top++;}int SPFA(int s,int t,int n){ memset(pre,-1,sizeof(pre)); memset(vist,0,sizeof(0)); for(int i =0 ; i <= n ;i++) dist[i]=inf ; int i,u,v; vist[s]=1;dist[s]=0; queue<int>q ; q.push(s); while(!q.empty()) { u=q.front(); q.pop(); vist[u]=0; for( i = head[u] ; i!=-1 ; i=edge[i].next) { v=edge[i].v ; if(edge[i].c && dist[v] > dist[u]+edge[i].cost) { dist[v] = dist[u]+edge[i].cost ; pre[v]=i; if(!vist[v]) { vist[v]=1; q.push(v); } } } } if(dist[t]==inf) return 0; return 1;}int MFMC(int s,int t,int n){ int minflow,mincost=0,flow=0; while(SPFA(s,t,n)) { minflow=inf ; for(int i=pre[t];i!=-1;i=pre[edge[i].u]) minflow=min(minflow,edge[i].c) ; for(int i=pre[t];i!=-1;i=pre[edge[i].u]) { edge[i].c -= minflow; edge[i^1].c += minflow ; } mincost += dist[t]*minflow ; flow+=minflow ; } return mincost ;}int main(){ int T,n,m,s,t,u,v,c; scanf("%d",&T); while(T--) { scanf("%d%d",&n,&m); top=0; memset(head,-1,sizeof(head)); s=0,t=2*n+1 ; while(m--) { scanf("%d%d%d",&u,&v,&c); add(u,v+n,1,c); } for(int i = 1 ; i <= n ; i++) add(s,i,1,0),add(i+n,t,1,0); int ans=MFMC(s,t,t+1); printf("%d\n",ans); } return 0;}
- hdu 3488 Tour (最小权匹配 / 费用流)
- HDU 3488 Tour 最小费用最大流||最大匹配
- hdu 1853 Cyclic Tour(最小权匹配/费用流)
- HDU 1853 Cyclic Tour && HDU 3488Tour 最小费用流
- hdu 3488 Tour【最小费用最大流】
- HDU 3488 Tour 用费用流解决完美匹配最小费用问题
- HDU 1853 Cyclic Tour【最小费用最大流 OR 带权二分图匹配】
- HDU 3488--Tour【最小费用最大流 && 有向环最小权值覆盖 && 经典】
- HDU 3488Tour(网络流之最小费用流)
- hdu 3488 Tour(最小费用流orKM算法)
- HDU 3488 Tour(最小费用流:有向环覆盖)
- HDU 3488 Tour (最小费用流 或 KM)
- HDU 1853 Cyclic Tour(最小费用流)
- HDU 3488 Tour 费用流
- hdu 3488 Tour (有向环最小权值覆盖,费用流)
- hdu 3488 Tour km二分匹配最小权
- hdu-1853-Tour-最小权匹配
- HDU 1853--Cyclic Tour【最小费用最大流 && 有向环最小权值覆盖 】
- 信号量(System V)
- hdu 1542 Atlantis(线段树,扫描线)
- hdu 4036 Rolling Hongshu
- 线程安全
- 输入法切换
- hdu 3488 Tour (最小权匹配 / 费用流)
- Android版Ibatis开源的ORM框架Aibatis介绍
- 音视频封装格式和编码格式
- 应用程序控制(自动启动、登录、退出等)
- Setup Factory 9.0 中的几个问题
- 移植uip-0.9到u-boot中出现undefined reference to `flash_info'错误的分析过程
- OutlookGrid:以Outlook样式分组和排列数据项
- vs2012配置opencv2.4.6
- 工作队列(workqueue)