HDU1853 Cyclic Tour KM算法 模版题
2013-10-25 20:10
513 查看
这道题目就是个模版题目,求的是走完图中所有点的最短的路径长度,KM算法 是 最大权匹配,算的是最大权值,但是我们在建图的时候 把权值改为负的就可以了,这样进行KM算法 算出来的 是最大的负数,其实就是最小的正数,
#include<iostream> #include<cstdio> #include<list> #include<algorithm> #include<cstring> #include<string> #include<queue> #include<stack> #include<map> #include<vector> #include<cmath> #include<memory.h> #include<set> #define ll long long #define LL __int64 #define eps 1e-8 const ll INF=9999999999999; using namespace std; #define M 400000100 #define inf 0xfffffff //vector<pair<int,int> > G; //typedef pair<int,int> P; //vector<pair<int,int>> ::iterator iter; // //map<ll,int>mp; //map<ll,int>::iterator p; //vector<int>G[8000]; int mp[1212][1212]; int marry[1212]; int lx[1212],ly[1212]; bool visx[1212],visy[1212]; int slack[1212]; char tempmp[1212][1212]; int dis[2][4]={0,-1,0,1,1,0,-1,0}; int n,m; int un,vn; void clear() { un=vn=0; memset(marry,-1,sizeof(marry)); /*memset(mp,0,sizeof(mp));*/ memset(ly,0,sizeof(ly)); for(int i=0;i<=n;i++) for(int j=0;j<=n;j++) mp[i][j]=-inf; } bool dfs(int x) { visx[x]=true; for(int i=1;i<=vn;i++) { if(visy[i]) continue; int temp=lx[x]+ly[i]-mp[x][i]; if(temp==0) { visy[i]=true; if(marry[i]==-1 || dfs(marry[i])) { marry[i]=x; return 1; } } else if(slack[i]>temp) slack[i]=temp; } return 0; } void KM() { for(int i=1;i<=n;i++) { lx[i]=-inf; for(int j=1;j<=n;j++) lx[i]=max(lx[i],mp[i][j]); } for(int k=1;k<=un;k++) { for(int i=1;i<=un;i++) slack[i]=inf; while(1) { memset(visx,false,sizeof(visx)); memset(visy,false,sizeof(visy)); if(dfs(k)) break; int d=inf; for(int i=1;i<=vn;i++) if(!visy[i] && d>slack[i]) d=slack[i]; for(int i=1;i<=un;i++) if(visx[i]) lx[i]-=d; for(int i=1;i<=vn;i++) { if(visy[i]) ly[i]+=d; else slack[i]-=d; } } } } int main(void) { while(cin>>n>>m) { clear(); un=n;//左集合元素数 vn=n;//右集合元素数 int u,v,w; for(int i=0;i<m;i++) { cin>>u>>v>>w; if(mp[u][v]<-w) mp[u][v]=-w;//这里被坑了 没考虑有重边,有的话取小的 } KM();//KM模版直接套 int ans=0; bool flag=false; for(int i=1;i<=un;i++) { if(marry[i]==-1 || mp[marry[i]][i]==-inf)//判断是否是完美匹配,若不是则输出-1 { flag=true; break; } ans+=mp[marry[i]][i]; } if(flag) puts("-1"); else cout<<-ans<<endl; } }
相关文章推荐
- HDU2255 奔小康赚大钱 又是984ms 飘过汗啊 最大权匹配 KM算法模版题
- 二分图相关概念 二分图最大匹配 二分图最大权匹配 poj3041 poj2195
- hdu2255
- bzoj 2539: [Ctsc2000]丘比特的烦恼 (KM算法)
- 最大权二分匹配—KM算法入门 && 模板
- UVALive 7226 Coin Swap
- hdoj 2255 奔小康赚大钱 (KM算法 详解+模板)
- poj2195Going Home(费用流或KM算法)
- uva11383(KM算法)
- 图论——二分匹配
- KM算法的一些其他用处
- HDU 3488 最小费用圈覆盖
- 最大权二分匹配
- 模板-KM算法
- zoj 2342 Roads
- POJ 2195-Going Home(KM算法/最小费用最大流算法)
- HDU 2255-奔小康赚大钱(Kuhn-Munkras算法/KM算法-完备匹配下的最大权匹配)
- POJ 3565 Ants (证明+KM算法)
- 例题5.24 少林决胜 UVa11383
- 例题5.23 蚂蚁 LA4043